如何防止sync.Pool创建两个实例

问题描述 投票:-2回答:1

我正在实现一个用于记录流利位的TCP连接池,这是代码

import (
    "fmt"
    "log"
    "net"
    "sync"
)

type FluentConnectionPool struct {
    sync.Mutex
    pool          *sync.Pool
}

func (fl *FluentConnectionPool) Log(message string) {
    fl.Lock()
    defer fl.Unlock()

    conn := fl.pool.Get().(*net.TCPConn)
    defer fl.pool.Put(conn)

    fmt.Printf("using: %v\n", conn.LocalAddr())

    if _, err := conn.Write([]byte(message)) ; err != nil {
        log.Fatal(err)
    }
}

func (fl *FluentConnectionPool) Close() {
    conn := fl.pool.Get().(*net.TCPConn)
    defer conn.Close()

    fmt.Printf("Closing: %v\n", conn.LocalAddr())
}

func New(address string) (*FluentConnectionPool, error) {
    fluentAddress, err := net.ResolveTCPAddr("tcp", address)

    if err != nil {
        return nil, err
    }

    pool := &sync.Pool{New: func() interface{} {
        connection, _ := net.DialTCP("tcp", nil, fluentAddress)
        return connection
    }}

    return &FluentConnectionPool{
        pool:          pool,
    }, nil
}

当我测试这样的代码时

import "time"

func main() {
    pool, _ := New("localhost:5170")
    defer pool.Close()

    for i := 0 ; i < 10 ; i++ {
        go func() {
               pool.Log(`{"data": {"name": "name here"}}`)
        }()
    }

    time.Sleep(1 * time.Second)
}

输出是这样的

using: 127.0.0.1:43990
using: 127.0.0.1:43990
using: 127.0.0.1:43990
using: 127.0.0.1:43990
using: 127.0.0.1:43990
using: 127.0.0.1:43990
using: 127.0.0.1:43990
using: 127.0.0.1:43990
using: 127.0.0.1:43990
using: 127.0.0.1:43994
Closing: 127.0.0.1:43994

尽管我已经锁定了功能,但我不明白为什么连接会创建两次(43990&43994),所以43990上的连接保持打开状态,您能解释一下为什么会这样吗?

谢谢!

go goroutine
1个回答
1
投票
Pool文档中的此内容可能会解释行为:

存储在池中的任何项目都可以随时自动删除,恕不另行通知。如果发生这种情况时,池中只有唯一的引用,则可能会释放该项目。

池可能已删除您使用的连接。

© www.soinside.com 2019 - 2024. All rights reserved.