久久久久久久视色,久久电影免费精品,中文亚洲欧美乱码在线观看,在线免费播放AV片

<center id="vfaef"><input id="vfaef"><table id="vfaef"></table></input></center>

    <p id="vfaef"><kbd id="vfaef"></kbd></p>

    
    
    <pre id="vfaef"><u id="vfaef"></u></pre>

      <thead id="vfaef"><input id="vfaef"></input></thead>

    1. 站長資訊網(wǎng)
      最全最豐富的資訊網(wǎng)站

      關(guān)于Golang連接池的幾種實(shí)現(xiàn)案例

      下面由golang教程欄目給大家介紹Golang連接池的幾種實(shí)現(xiàn)案例,希望對需要的朋友有所幫助!

      關(guān)于Golang連接池的幾種實(shí)現(xiàn)案例

      因?yàn)門CP的三次握手等等原因,建立一個連接是一件成本比較高的行為。所以在一個需要多次與特定實(shí)體交互的程序中,就需要維持一個連接池,里面有可以復(fù)用的連接可供重復(fù)使用。

      而維持一個連接池,最基本的要求就是要做到:thread safe(線程安全),尤其是在Golang這種特性是goroutine的語言中。

      實(shí)現(xiàn)簡單的連接池

      type Pool struct {     m sync.Mutex //保證多個goroutine訪問時候,closed的線程安全     res chan io.Closer //連接存儲的chan     factory func() (io.Closer,error) //新建連接的工廠方法     closed bool //連接池關(guān)閉標(biāo)志 }

      這個簡單的連接池,我們利用chan來存儲池里的連接。而新建結(jié)構(gòu)體的方法也比較簡單:

      func New(fn func() (io.Closer, error), size uint) (*Pool, error) {     if size <= 0 {         return nil, errors.New("size的值太小了。")     }     return &Pool{         factory: fn,         res:     make(chan io.Closer, size),     }, nil }

      只需要提供對應(yīng)的工廠函數(shù)和連接池的大小就可以了。

      獲取連接

      那么我們要怎么從中獲取資源呢?因?yàn)槲覀儍?nèi)部存儲連接的結(jié)構(gòu)是chan,所以只需要簡單的select就可以保證線程安全:

      //從資源池里獲取一個資源 func (p *Pool) Acquire() (io.Closer,error) {     select {     case r,ok := <-p.res:         log.Println("Acquire:共享資源")         if !ok {             return nil,ErrPoolClosed         }         return r,nil     default:         log.Println("Acquire:新生成資源")         return p.factory()     } }

      我們先從連接池的res這個chan里面獲取,如果沒有的話我們就利用我們早已經(jīng)準(zhǔn)備好的工廠函數(shù)進(jìn)行構(gòu)造連接。同時我們在從res獲取連接的時候利用ok先確定了這個連接池是否已經(jīng)關(guān)閉。如果已經(jīng)關(guān)閉的話我們就返回早已經(jīng)準(zhǔn)備好的連接已關(guān)閉錯誤。

      關(guān)閉連接池

      那么既然提到關(guān)閉連接池,我們是怎么樣關(guān)閉連接池的呢?

      //關(guān)閉資源池,釋放資源 func (p *Pool) Close() {     p.m.Lock()     defer p.m.Unlock()     if p.closed {         return     }     p.closed = true     //關(guān)閉通道,不讓寫入了     close(p.res)     //關(guān)閉通道里的資源     for r:=range p.res {         r.Close()     } }

      這邊我們需要先進(jìn)行p.m.Lock()*上鎖操作,這么做是因?yàn)槲覀冃枰獙Y(jié)構(gòu)體里面的*closed進(jìn)行讀寫。需要先把這個標(biāo)志位設(shè)定后,關(guān)閉res這個chan,使得Acquire方法無法再獲取新的連接。我們再對res這個chan里面的連接進(jìn)行Close操作。

      釋放連接

      釋放連接首先得有個前提,就是連接池還沒有關(guān)閉。如果連接池已經(jīng)關(guān)閉再往res里面送連接的話就好觸發(fā)panic。

      func (p *Pool) Release(r io.Closer){     //保證該操作和Close方法的操作是安全的     p.m.Lock()     defer p.m.Unlock()     //資源池都關(guān)閉了,就省這一個沒有釋放的資源了,釋放即可     if p.closed {         r.Close()         return     }     select {     case p.res <- r:         log.Println("資源釋放到池子里了")     default:         log.Println("資源池滿了,釋放這個資源吧")         r.Close()     } }

      贊(0)
      分享到: 更多 (0)
      網(wǎng)站地圖   滬ICP備18035694號-2    滬公網(wǎng)安備31011702889846號