简体   繁体   English

如何在递归函数中设置互斥锁和sync.waitgroup?

[英]How to set mutex and sync.waitgroup in recursive function?

I wrote a little code in Go to parse a site and retrieve all link and their Http Response. 我在Go中编写了一些代码来解析站点并检索所有链接及其Http响应。 My code works well but I would like to add GoRoutines to see how it works in recursive function. 我的代码运行良好,但是我想添加GoRoutines来看看它在递归函数中的工作方式。

package main
import (
    "fmt"
    "io/ioutil"
    "net/http"
    "regexp"
    "strings"
    "sync"
)

type linkWeb struct {
    Link string
    Code string
}

func parseLink(siteName string, arrayError []linkWeb) (arrayResult []linkWeb) {
    var mutex = &sync.Mutex{}
    var wg = sync.WaitGroup{}
    var baseSite = siteName
    site, _ := http.Get(baseSite)
    html, _ := ioutil.ReadAll(site.Body)
    errorCodeHTTP := site.Status
    mutex.Lock()
    errorArray := arrayError
    mutex.Unlock()
    allJs := regexp.MustCompile(`src="[^"]*"+`)
    allA := regexp.MustCompile(`(.)*href="[^"]*"+`)
    var resultsJs = allJs.FindAllStringSubmatch(string(html), -1)
    var resultUrls = allA.FindAllStringSubmatch(string(html), -1)
    resultsJs = append(resultsJs, resultUrls...)
    for _, linkJs := range resultsJs {
        wg.Add(1)
        go func() {
            re := regexp.MustCompile(`(href|src)(.)*="[^"]*"`)
            var execReg = re.FindAllStringSubmatch(linkJs[0], -1)
            link := regexp.MustCompile(`"(.)*"`)
            var linkCenter = link.FindAllStringSubmatch(execReg[0][0], -1)
            resultrmvbefore := strings.TrimPrefix(linkCenter[0][0], "\"")
            resultrmvafter := strings.TrimSuffix(resultrmvbefore, "\"")
            var already = 0
            mutex.Lock()
            for _, itemURL := range errorArray {
                if resultrmvafter == itemURL.Link {
                    already = 1
                }
            }
            mutex.Unlock()
            if already == 0{
                var actualState = linkWeb{resultrmvafter, "-> " + errorCodeHTTP + "\r\n"}
                mutex.Lock()
                errorArray = append(errorArray, actualState)
                mutex.Unlock()
                return
            } else {
                if already == 0 {
                    var actualState = linkWeb{resultrmvafter, "-> " + errorCodeHTTP + "\r\n"}
                    mutex.Lock()
                    errorArray = append(errorArray, actualState)
                    var arrayReturn = errorArray
                    mutex.Unlock()
                    parseLink(resultrmvafter, arrayReturn)
                }
            }
            wg.Done()
        }()
    }
    wg.Wait()
    return
}
func main() {
    var arrayError []linkWeb
    var resultArray = parseLink("https://www.golem.ai/", arrayError)
}

I just don't know if it's necessary to pass my syncGroup as a function parameter because I made a test and I don't see any changes. 我只是不知道是否有必要将syncGroup作为函数参数传递,因为我进行了测试并且没有看到任何更改。 I read the docs but I don't know if my problem is bound to my recursive function or something that I don't understand with Golang. 我阅读了文档,但我不知道我的问题是否与我的递归函数或Golang不了解的东西有关。 Thank you very much for your help :) 非常感谢您的帮助 :)

There is nothing inherently special about recursion wrt mutexes, wait groups or other objects. 递归wrt互斥,等待组或其他对象在本质上没有什么特别的。 It's the same as any function call. 它与任何函数调用相同。 Since mutexes are mutable, you have to be careful to pass them around by pointers - and that should be that. 由于互斥锁是可变的,因此您必须小心通过指针传递它们-那就应该如此。 To debug this it's often useful to printf the address of the object in caller and callee and ensure they're the same object. 要调试它,通常在调用方和被调用方中打印对象的地址并确保它们是同一对象通常很有用。

To get more specific help with your code snippet, I'd suggest you minimize it to something much simpler that demonstrates your problem: https://stackoverflow.com/help/mcve 为了获得有关代码段的更多具体帮助,建议您将其最小化,以更简单地说明问题: https : //stackoverflow.com/help/mcve

From a quick look at your code, each call to parseLink creates a new mutex and wait group, is this what you intended? 快速浏览一下代码,每次对parseLink调用parseLink创建一个新的互斥体和等待组,这是您想要的吗?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM