Golang如何实现并发处理

Golang如何实现并发处理 你好, 基本上我有一个名为 a 的切片,我正在检查其中的每个值是否可达。

这是我尝试做的:

func check(a []string){

    var subdom []string

	for i := 0; i < len(a); i++ {
		_, error := net.LookupIP(a[i])
    		if error == nil {
        		subdom = append(subdom, a[i])
        		fmt.Println(subdom)
    		} 
	}

}

有什么方法可以让这个操作并发执行吗?如果可以,具体怎么做?我是并发编程的新手。希望你能提供帮助, 提前感谢!


更多关于Golang如何实现并发处理的实战教程也可以访问 https://www.itying.com/category-94-b0.html

5 回复

非常感谢,顺序并不重要。

更多关于Golang如何实现并发处理的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


抱歉,最后问一下,既然我在做 err == nil 的判断,这个 for 循环是不是在等待一个永远不会返回的结果?

go func(a string, results chan string) {
			_, error := net.LookupIP(a)
    		if error == nil {
        		results <- a
        		fmt.Println(a)
    		}
		}(a, results)

您可以将 for 循环体转换为一个 goroutine。但您需要修改它,使得这样的 goroutine 不会并发地向 subdom 追加数据。

相反,在 check 中创建一个输出通道,将其传递给循环中启动的每个 goroutine,如果 error == nil,则将 a[i] 写入此通道,而不是将其追加到 subdom。在 for 循环之后,从 check 中的通道读取 len(a)string,并将每个读取到的 string 追加到 subdom

您明白这个思路了吗?

假设部分地,我有一些问题:

  1. 如果没有 for 循环,我该如何使用 a[i](如果我没有 for i := 0 等语句)?
  2. 我不太理解 在 for 循环后的检查中从通道读取 len(a) 个字符串,将每个读取的字符串追加到 subdom 这句话。
  3. 我是否应该编写 3/4 个不同名称的函数,它们包含并作为 goroutine 在 main 函数中调用?
_, error := net.LookupIP(a[i])
    		if error == nil {
        		subdom = append(subdom, a[i]) //我知道这里需要修改
        		fmt.Println(subdom)
    		} 

谢谢

你可以使用goroutine和channel来实现并发处理。这里是一个改进版本:

func check(a []string) []string {
    var subdom []string
    ch := make(chan string)
    var wg sync.WaitGroup
    
    for _, domain := range a {
        wg.Add(1)
        go func(d string) {
            defer wg.Done()
            _, err := net.LookupIP(d)
            if err == nil {
                ch <- d
            }
        }(domain)
    }
    
    go func() {
        wg.Wait()
        close(ch)
    }()
    
    for domain := range ch {
        subdom = append(subdom, domain)
        fmt.Println(domain)
    }
    
    return subdom
}

或者使用带缓冲的channel和worker池:

func check(a []string) []string {
    var subdom []string
    ch := make(chan string, len(a))
    var mu sync.Mutex
    var wg sync.WaitGroup
    
    for _, domain := range a {
        wg.Add(1)
        go func(d string) {
            defer wg.Done()
            _, err := net.LookupIP(d)
            if err == nil {
                mu.Lock()
                subdom = append(subdom, d)
                mu.Unlock()
                fmt.Println(d)
            }
        }(domain)
    }
    
    wg.Wait()
    return subdom
}

第一个示例使用channel收集结果,第二个示例使用互斥锁保护共享切片。两个版本都能并发执行DNS查询。

回到顶部