当前位置:网站首页>[golang] quick review guide quickreview (x) -- goroutine pool
[golang] quick review guide quickreview (x) -- goroutine pool
2022-06-23 20:05:00 【DDGarfield】
goroutine The stack of is small at the beginning of its life cycle , Maybe it's just 2KB, But it is not fixed , Can be increased or decreased as required . Although we can create many without brains goroutine To perform operations , But if something happens to the program ,goroutine May soar to occupy memory , Everything becomes uncontrollable , For example, we create by looping goroutine, When the cycle condition is satisfied , Create huge goroutine, In severe cases, the system will crash . The blogger is also through teacher Yang Xu TCP This problem was found in the port scanner .
1. Circular scanning
Don't use goroutine, Direct loop scan port .
package main
import (
"fmt"
"net"
"time"
)
func main() {
fmt.Println("TCP Port scan start ...")
start := time.Now()
for i := 1; i <= 20; i++ {
address := fmt.Sprintf("192.168.0.109:%d", i)
conn, err := net.Dial("tcp", address)
if err != nil {
fmt.Printf(" %s close \n", address)
continue
}
conn.Close()
fmt.Printf(" %s open \n", address)
}
elasped := time.Since(start) / 1e9
fmt.Printf("\n After %d second \n", elasped)
}
TCP Port scan start ...
192.168.0.109:1 close
192.168.0.109:2 close
192.168.0.109:3 close
192.168.0.109:4 close
192.168.0.109:5 close
192.168.0.109:6 close
192.168.0.109:7 close
192.168.0.109:8 close
192.168.0.109:9 close
192.168.0.109:10 close
192.168.0.109:11 close
192.168.0.109:12 close
192.168.0.109:13 close
192.168.0.109:14 close
192.168.0.109:15 close
192.168.0.109:16 close
192.168.0.109:17 close
192.168.0.109:18 close
192.168.0.109:19 close
192.168.0.109:20 close
After 40 second
2. Concurrent scanning
utilize goroutine Concurrent scanning
package main
import (
"fmt"
"net"
"sync"
"time"
)
var wg sync.WaitGroup
func main() {
fmt.Println("TCP Port scan start ...")
start := time.Now()
for i := 1; i <= 20; i++ {
wg.Add(1)
go func(i int) {
defer wg.Done()
address := fmt.Sprintf("192.168.0.109:%d", i)
conn, err := net.Dial("tcp", address)
if err != nil {
fmt.Printf(" %s close \n", address)
return
}
conn.Close()
fmt.Printf(" %s open \n", address)
}(i)
}
wg.Wait()
elasped := time.Since(start) / 1e9
fmt.Printf(" After %d second ", elasped)
}
TCP Port scan start ...
192.168.0.109:4 close
192.168.0.109:6 close
192.168.0.109:11 close
192.168.0.109:7 close
192.168.0.109:8 close
192.168.0.109:14 close
192.168.0.109:3 close
192.168.0.109:20 close
192.168.0.109:16 close
192.168.0.109:12 close
192.168.0.109:1 close
192.168.0.109:17 close
192.168.0.109:18 close
192.168.0.109:13 close
192.168.0.109:9 close
192.168.0.109:10 close
192.168.0.109:5 close
192.168.0.109:15 close
192.168.0.109:19 close
192.168.0.109:2 close
After 2 second
Even if the code is changed to full port 1~65535, Time is only 21s
package main
import (
"fmt"
"net"
"sync"
"time"
)
var wg sync.WaitGroup
func main() {
fmt.Println("TCP Port scan start ...")
start := time.Now()
for i := 1; i <= 65535; i++ {
wg.Add(1)
go func(i int) {
defer wg.Done()
address := fmt.Sprintf("192.168.0.109:%d", i)
conn, err := net.Dial("tcp", address)
if err != nil {
fmt.Printf(" %s close \n", address)
return
}
conn.Close()
fmt.Printf(" %s open \n", address)
}(i)
}
wg.Wait()
elasped := time.Since(start) / 1e9
fmt.Printf("\n After %d second \n", elasped)
}
...
192.168.0.109:39702 close
192.168.0.109:37282 close
192.168.0.109:39490 close
192.168.0.109:39795 close
192.168.0.109:39613 close
192.168.0.109:39707 close
192.168.0.109:39723 close
192.168.0.109:39732 close
192.168.0.109:39806 close
192.168.0.109:39682 close
192.168.0.109:39809 close
192.168.0.109:39663 close
192.168.0.109:40006 close
192.168.0.109:39712 close
192.168.0.109:39804 close
192.168.0.109:39731 close
192.168.0.109:39701 close
192.168.0.109:39810 close
192.168.0.109:39725 close
192.168.0.109:39805 close
192.168.0.109:39713 close
192.168.0.109:39489 close
192.168.0.109:39791 close
192.168.0.109:39640 close
192.168.0.109:39667 close
192.168.0.109:39661 close
After 21 second
It can also be seen here that goroutine Do concurrent operations , It's really fast .
3.goroutine pool( pool )
This is done at the end of the previous section , It was created. 6w many times goroutine, If the value is larger ,100w,1 $ ( Of course IP The port number is not so large ), Just a bold experiment : Then you can see the memory in the floating window that monitors the memory No, no, no, No It's going up , Memory quickly ran out , Until the system is stuck , Even blue screen .
To avoid that , We urgently need to create a mechanism similar to thread pool , To limit what we create goroutine The number of , And reuse . Create a fixed number of m individual goroutine, utilize channel The mechanism of , Go to channel In the transfer n Data , Then assign to this m individual goroutine,m<=n.
It is also a port scanning task , The code transformation is as follows :
package main
import (
"fmt"
"net"
)
func main() {
fmt.Println("TCP Port scan start ...")
fmt.Println(" The following ports are open :")
n := make(chan int, 100)
results := make(chan int, 100)
// establish 20000 individual goroutine
for m := 0; m < 20000; m++ {
go worker(n, results)
}
//channel Represents the number of tasks
for i := 1; i < 65535; i++ {
n <- i
}
close(n)
// result
for port := range results {
fmt.Println(port)
}
}
func worker(ports <-chan int, results chan<- int) {
for port := range ports {
address := fmt.Sprintf("192.168.0.109:%d", port)
conn, err := net.Dial("tcp", address)
if err != nil {
// fmt.Printf(" %s close \n", address)
continue
}
conn.Close()
// fmt.Printf(" %s open \n", address)
results <- port
}
}
TCP Port scan start ...
The following ports are open :
80
81
139
902
443
445
135
912
1433
2383
2179
3306
5357
5040
7680
8080
33060
43094
43095
49672
49664
49667
49666
49670
49665
50272
边栏推荐
- 好用的人事管理软件有哪些?人事管理系统软件排名!
- How to write a great online user manual in 7 steps
- Leaders of Hangcheng street, Bao'an District and their delegation visited lianchengfa for investigation
- Development of block hash quiz game system (DAPP)
- How to avoid the "black swan" incident in the gene field: a security war behind a preventive "recall"
- 重庆 奉节耀奎塔,建成后当地连中五名进士,是川江航运的安全塔
- 【Golang】类型转换归纳总结
- Rendering of kotlin jetpack compose tab using animatedvisibility
- Hardware development notes (6): basic process of hardware development, making a USB to RS232 module (5): creating USB package library and associating principle graphic devices
- LeetCode 1079. movable-type printing
猜你喜欢

Hardware development notes (6): basic process of hardware development, making a USB to RS232 module (5): creating USB package library and associating principle graphic devices

Importance and purpose of test

Save: software analysis, verification and test platform

Can the biggest gamefi crash victim survive the bear market in May| May Monthly Report

Flagai Feizhi: AI basic model open source project, which supports one click call of OPT and other models

Eight misunderstandings, broken one by one (final): the cloud is difficult to expand, the customization is poor, and the administrator will lose control?

LeetCode 260. 只出现一次的数字 III

LeetCode 473. Match to square

20 provinces and cities announce the road map of the meta universe

小程序开发框架推荐
随机推荐
教你如何用网页开发桌面应用
Kubernetes 资源拓扑感知调度优化
火线沙龙第26期-多云安全专场
【Golang】快速复习指南QuickReview(四)——函数
Tcp/udp Fundamentals
Helix QAC is updated to 2022.1 and will continue to provide high standard compliance coverage
LeetCode 473. Match to square
FPGA based electromagnetic ultrasonic pulse compression detection system paper + source file
JDBC 在性能測試中的應用
如何通过7个步骤编写出色的在线用户手册
GL Studio 5 安装与体验
Chaos engineering, learn about it
科班出身,结果外包都不要
硬件开发笔记(六): 硬件开发基本流程,制作一个USB转RS232的模块(五):创建USB封装库并关联原理图元器件
技术分享| WVP+ZLMediaKit实现摄像头GB28181推流播放
【Golang】怎样优雅的清空切片
The golden nine silver ten, depends on this detail, the offer obtains the soft hand!
墨天轮访谈 | IvorySQL王志斌—IvorySQL,一个基于PostgreSQL的兼容Oracle的开源数据库
【Golang】快速复习指南QuickReview(二)——切片slice
打新债需要具备什么条件 打新债安全吗