分享
这是一个创建于 的主题,其中的信息可能已经有所发展或是发生改变。
我一个TCP服务,希望从外部关闭Listener,但这样就在listener.Close()与listener.Accept()之间产生了race。请教有什么好的解决办法?
简单的示例代码如下, 加"-race"参数运行,再ctrl+c退出运行,就会报race问题:
```
package main
import (
"log"
"net"
"os"
"os/signal"
"syscall"
"time"
)
var listener *net.TCPListener
// tcp服务
func tcpServer() {
addr, err := net.ResolveTCPAddr("tcp4", ":6666")
if err != nil {
log.Fatalln(err)
}
listener, err = net.ListenTCP("tcp4", addr)
if err != nil {
log.Fatalln(err)
}
for {
c, err := listener.AcceptTCP()
if err != nil {
if err.(*net.OpError).Err == net.ErrClosed {
log.Println("listener closed")
return
}
log.Println(err)
continue
}
connHandler(c)
}
}
// 新连接处理
func connHandler(c *net.TCPConn) {
defer func() {
c.Close()
log.Printf("%s closed", c.RemoteAddr().String())
}()
log.Printf("New connection: %s", c.RemoteAddr().String())
buf := make([]byte, 128)
for {
n, err := c.Read(buf)
if err != nil {
return
}
log.Println(buf[:n])
}
}
// 关闭listener
func listenerClose() {
if listener != nil {
listener.Close()
}
}
func main() {
sigs := make(chan os.Signal, 1)
signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
go tcpServer()
<-sigs
listenerClose()
time.Sleep(time.Millisecond * 200)
}
```
有疑问加站长微信联系(非本文作者)
入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889
关注微信2992 次点击
添加一条新回复
(您需要 后才能回复 没有账号 ?)
- 请尽量让自己的回复能够对别人有帮助
- 支持 Markdown 格式, **粗体**、~~删除线~~、
`单行代码` - 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
- 图片支持拖拽、截图粘贴等方式上传