Golang 中国

求限制goroutine数量的方法

package main

import (
    "net"
    "fmt"
    "strconv"
    "time"
)

func demo9MincIP(ip net.IP) {

    for j := len(ip) - 1; j >= 0; j-- {
        ip[j]++
        if ip[j] > 0 {
            break
        }
    }
}


func demo9Miplist(cidr string) []string {
    var list []string
    ip, ipNet, err := net.ParseCIDR(cidr)

    if err != nil {
        ip = net.ParseIP(cidr)
        list = append(list, ip.String())
        return list
    }
    for ip := ip.Mask(ipNet.Mask); ipNet.Contains(ip); demo9MincIP(ip) {

        list = append(list, ip.String())
    }
    return list
}


func demo9chantest(ip_port string,flag chan int){
    defer func() {

        if err := recover(); err != nil {

            //fmt.Println("work failed:", err)

        }

    }()

    tcpAddr, err := net.ResolveTCPAddr("tcp4", ip_port)
    if err != nil {

    } else {
        conn, err := net.DialTimeout("tcp", tcpAddr.String(), 2*time.Second)
        if err != nil {

        } else {
            fmt.Println("[+]", ip_port, "Open")

            conn.Close()
        }
    }
    flag <- 1
}

func main() {
    var portlist = []int{21,22,23,25,587,53,79,80,88,110,111,113,135,139,161,264,389,443,445,512,513,514,548,554,593,873,1099,1433,1521,2049,3260,5432,5900,6000,9100,9160,10000,11211,27017,27018,44818,47808,8080,8443,8554,3306,9999,500,3389}
    routineCtl := make(chan int,200) 
    ips := demo9Miplist("192.168.1.0/24")
    count:=0

    for _, ports := range portlist {
        for _,ip :=range ips[1:len(ips)-1]{
            count = count+1
            go demo9chantest(ip+":"+strconv.Itoa(ports), routineCtl)

        }
    }

    for j:= 0; j < count; j++ {

        <-routineCtl

    }

}

spidergo 于 2017-07-03 10:10 修改
2 回复
xgfone
#1 xgfone • 2017-07-07 10:02

自已写一个 Goroutine Pool,比如:https://gowalker.org/github.com/xgfone/go-tools/pools#GoPool 。大致思路是:写一个计数器,当启动一个 Goroutine 时,加 1,当 Goroutine 结束时,减 1。

另一个方法是:写一个 Goroutine 任务池(可以设置大小),把每个任务都放到一个管道 Channel 中,而任务池中的 Goroutine 会从管道 Channel 中取任务并处理。参见实现:https://gowalker.org/github.com/xgfone/go-tools/worker#Dispatcher

yinziyang
#2 yinziyang • 2017-07-07 11:40
func demo9chantest(wg *sync.WaitGroup, routineCtl chan string){
    defer wg.Done()
    for ip := range routineCtl{
        // bala bala  ...
    }
}


func main() {
    var portlist = []int{21,22,23,25,587,53,79,80,88,110,111,113,135,139,161,264,389,443,445,512,513,514,548,554,593,873,1099,1433,1521,2049,3260,5432,5900,6000,9100,9160,10000,11211,27017,27018,44818,47808,8080,8443,8554,3306,9999,500,3389}
    routineCtl := make(chan string,200) 
    ips := demo9Miplist("192.168.1.0/24")

    var processNum = 10
    var wg = &sync.WaitGroup{}


    for i:=0; i<processNum; i++{
        wg.Add(1)
        go demo9chantest(wg, routineCtl)
    }


    for _, ports := range portlist {
        for _,ip :=range ips[1:len(ips)-1]{
            ip = ip+":"+strconv.Itoa(ports)
            routineCtl <- ip
        }
    }

    close(routineCtl)
    wg.Wait()
}
需要 登录 后方可回复, 如果你还没有账号你可以 注册 一个帐号。