环境:go 1.15.6 mac 11.1
下面代码使用net.DialTimeout扫描端口是否开放,超时设置为1s,目标端口99%的都会触发超时
运行后大概率线程数超过8192,然后开始报错
尝试过:
1、去掉ants协程池管理库,直接起go程,依然存在问题
2、将协程并发数降低到1w,线程数依然暴涨,但是超过8192几率小一些
3、将net.DialTimeout换成net.Dial,线程数降到一百多,但是速度慢太多了,几分钟后dial才会自己返回err
在网上找到一片类似情况的文章:[一个 Go 程序系统线程暴涨的问题](https://zhuanlan.zhihu.com/p/22474724)
也是由timeout引起,现在想知道怎么到达有timeout的效果又不会让线程暴涨?
还有一个问题,同时运行的go程过多(一万),tcp连接正常开放的端口也会扫不出来,可能不是个例,在网上找的一个go做的扫描工具也会存在目标数过多,扫不出来的情况
![image.png](https://static.studygolang.com/210115/7666a74083c143c29d4e093ed3f10c8e.png)
```go
func connectPort(addr string, timeout int) {
conn, err := net.DialTimeout("tcp", addr, time.Duration(timeout)*time.Millisecond)
if err != nil {
return
}
defer conn.Close()
println(addr)
}
```
```go
main:
ips := cidr.Expand(conf.ip)
var wg sync.WaitGroup
task := func(addr interface{}) {
defer wg.Done()
connectPort(addr.(string), conf.timeout)
}
// 已配置过maxfiles 102400 102400
p, _ := ants.NewPoolWithFunc(65536, task)
defer p.Release()
for _, ip := range ips {
wg.Add(1)
_ = p.Invoke(ip + ":" + conf.port)
}
wg.Wait()
println(len(ips))
```
```
报错:
oroutine 3879 [runnable]:
syscall.syscall(0x109e700, 0xdc0, 0x0, 0x0, 0x0, 0x0, 0x0)
/usr/local/Cellar/go/1.15.6/libexec/src/runtime/sys_darwin.go:63 +0x2e
syscall.Close(0xdc0, 0xc0002931c0, 0xc001c15840)
/usr/local/Cellar/go/1.15.6/libexec/src/syscall/zsyscall_darwin_amd64.go:519 +0x4c
internal/poll.(*FD).destroy(0xc0017d6180, 0x3215001, 0x0)
/usr/local/Cellar/go/1.15.6/libexec/src/internal/poll/fd_unix.go:77 +0x43
internal/poll.(*FD).decref(0xc0017d6180, 0x1, 0x0)
/usr/local/Cellar/go/1.15.6/libexec/src/internal/poll/fd_mutex.go:213 +0x45
internal/poll.(*FD).Close(0xc0017d6180, 0xc0017d6180, 0x0)
/usr/local/Cellar/go/1.15.6/libexec/src/internal/poll/fd_unix.go:99 +0x4f
net.(*netFD).Close(0xc0017d6180, 0x1167f20, 0xc0017d4d20)
/usr/local/Cellar/go/1.15.6/libexec/src/net/fd_posix.go:37 +0x4f
net.socket(0x1167f20, 0xc0017d4d20, 0x113d1f3, 0x3, 0x2, 0x1, 0x0, 0x0, 0x1168400, 0x0, ...)
/usr/local/Cellar/go/1.15.6/libexec/src/net/sock_posix.go:71 +0x1f2
net.internetSocket(0x1167f20, 0xc0017d4d20, 0x113d1f3, 0x3, 0x1168400, 0x0, 0x1168400, 0xc0017aee70, 0x1, 0x0, ...)
/usr/local/Cellar/go/1.15.6/libexec/src/net/ipsock_posix.go:141 +0x145
net.(*sysDialer).doDialTCP(0xc0017d6100, 0x1167f20, 0xc0017d4d20, 0x0, 0xc0017aee70, 0x111a660, 0x124c9a0, 0x0)
/usr/local/Cellar/go/1.15.6/libexec/src/net/tcpsock_posix.go:65 +0xc5
net.(*sysDialer).dialTCP(0xc0017d6100, 0x1167f20, 0xc0017d4d20, 0x0, 0xc0017aee70, 0x106a9a0, 0xc001c15b50, 0x655abf5a)
/usr/local/Cellar/go/1.15.6/libexec/src/net/tcpsock_posix.go:61 +0xd7
net.(*sysDialer).dialSingle(0xc0017d6100, 0x1167f20, 0xc0017d4d20, 0x1167260, 0xc0017aee70, 0x0, 0x0, 0x0, 0x0)
/usr/local/Cellar/go/1.15.6/libexec/src/net/dial.go:580 +0x5e5
net.(*sysDialer).dialSerial(0xc0017d6100, 0x1167f20, 0xc0017d4d20, 0xc0017bc950, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0)
/usr/local/Cellar/go/1.15.6/libexec/src/net/dial.go:548 +0x152
net.(*Dialer).DialContext(0xc001c15e60, 0x1167ee0, 0xc000016100, 0x113d1f3, 0x3, 0xc000538ec0, 0x11, 0x0, 0x0, 0x0, ...)
/usr/local/Cellar/go/1.15.6/libexec/src/net/dial.go:425 +0x6e5
net.(*Dialer).Dial(...)
/usr/local/Cellar/go/1.15.6/libexec/src/net/dial.go:348
net.DialTimeout(0x113d1f3, 0x3, 0xc000538ec0, 0x11, 0x3b9aca00, 0x0, 0xc00152e310, 0xc0015195b8, 0x0)
/usr/local/Cellar/go/1.15.6/libexec/src/net/dial.go:334 +0xba
main.connectPort(0xc000538ec0, 0x11, 0x3e8)
/Library/project/gostart/1.go:27 +0x6f
main.main.func1(0x1113940, 0xc00152e300)
/Library/project/gostart/1.go:77 +0x7c
github.com/panjf2000/ants/v2.(*goWorkerWithFunc).run.func1(0xc001542030)
/Library/project/gostart/vendor/github.com/panjf2000/ants/v2/worker_func.go:68 +0xb0
created by github.com/panjf2000/ants/v2.(*goWorkerWithFunc).run
/Library/project/gostart/vendor/github.com/panjf2000/ants/v2/worker_func.go:48 +0x4c
```
有疑问加站长微信联系(非本文作者)