欧美亚洲中文,在线国自产视频,欧洲一区在线观看视频,亚洲综合中文字幕在线观看

      1. <dfn id="rfwes"></dfn>
          <object id="rfwes"></object>
        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的三次握手等等原因,建立一個(gè)連接是一件成本比較高的行為。所以在一個(gè)需要多次與特定實(shí)體交互的程序中,就需要維持一個(gè)連接池,里面有可以復(fù)用的連接可供重復(fù)使用。

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

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

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

          這個(gè)簡單的連接池,我們利用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就可以保證線程安全:

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

          關(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)行讀寫。需要先把這個(gè)標(biāo)志位設(shè)定后,關(guān)閉res這個(gè)chan,使得Acquire方法無法再獲取新的連接。我們再對res這個(gè)chan里面的連接進(jìn)行Close操作。

          釋放連接

          釋放連接首先得有個(gè)前提,就是連接池還沒有關(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)閉了,就省這一個(gè)沒有釋放的資源了,釋放即可     if p.closed {         r.Close()         return     }     select {     case p.res <- r:         log.Println("資源釋放到池子里了")     default:         log.Println("資源池滿了,釋放這個(gè)資源吧")         r.Close()     } }

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