Go 如何防止同步池创建两个实例

Go 如何防止同步池创建两个实例,go,goroutine,Go,Goroutine,我正在实现一个TCP连接池,用于记录到fluent位,下面是代码 导入( “fmt” “日志” “净额” “同步” ) 类型FluentConnectionPool结构{ 同步互斥 池*sync.pool } func(fl*FluentConnectionPool)日志(消息字符串){ 弗洛克 延迟fl.Unlock() conn:=fl.pool.Get()(*net.TCPConn) 延迟fl.pool.Put(康涅狄格州) fmt.Printf(“使用:%v\n”,conn.LocalA

我正在实现一个TCP连接池,用于记录到fluent位,下面是代码

导入(
“fmt”
“日志”
“净额”
“同步”
)
类型FluentConnectionPool结构{
同步互斥
池*sync.pool
}
func(fl*FluentConnectionPool)日志(消息字符串){
弗洛克
延迟fl.Unlock()
conn:=fl.pool.Get()(*net.TCPConn)
延迟fl.pool.Put(康涅狄格州)
fmt.Printf(“使用:%v\n”,conn.LocalAddr())
如果3;,err:=conn.Write([]字节(消息));err!=nil{
log.Fatal(错误)
}
}
func(fl*FluentConnectionPool)关闭(){
conn:=fl.pool.Get()(*net.TCPConn)
延迟连接关闭()
fmt.Printf(“关闭:%v\n”,conn.LocalAddr())
}
func New(地址字符串)(*FluentConnectionPool,错误){
fluentAddress,err:=net.ResolveTCPAddr(“tcp”,地址)
如果错误!=零{
返回零,错误
}
池:=&sync.pool{New:func()接口{}{
连接:=net.DialTCP(“tcp”,无,fluentAddress)
回路连接
}}
返回和FluentConnectionPool{
水池:水池,
},零
}
当我像这样测试代码时

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
导入“时间”
func main(){
池:=新建(“本地主机:5170”)
延迟池。关闭()
对于i:=0;i<10;i++{
go func(){
Log(`{“data”:{“name”:“name here”}}}`)
}()
}
时间。睡眠(1*时间。秒)
}
输出如下

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上的连接保持打开状态,你能解释一下为什么会发生这种情况吗


谢谢大家!

来自
池的
文档可能解释了以下行为:

存储在池中的任何项目都可以随时自动删除,无需通知。如果发生这种情况时池持有唯一引用,则该项可能被解除分配


很可能池删除了您使用的连接

互斥是做什么用的?看起来它只是锁定了对
池的访问,该池已经是线程安全的,您可以从它位于
sync
包及其中看出。存储在sync.Pool中的项目可能会自动删除。自动删除第一个连接后,将创建第二个连接。
FluentConnectionPool.Close中的代码假定池最多有一个连接。锁确保池中的连接不超过一个。为什么要使用池而不是字段来保持连接?这看起来也像是对
sync.pool
的完全误用,sync.pool是一个对象池,而不是连接池。该实现假定池中的值未被使用,并且可以随时删除。其目的不是汇集活动连接;它的目的是将实例化成本可能很高的对象池化。不适合将连接存储在sync.pool中,因为无法保证何时调用被逐出连接的Close方法,或者是否调用该方法。是的,谢谢大家!