从两个不同的goroutine同时调用一个方法是否安全?

时间:2018-04-26 18:30:57

标签: go concurrency goroutine

我有两个goroutine go doProcess_A()go doProcess_B()。两者都可以调用saveData(),这是一种非goroutine方法。

我应该使用 go saveData()而不是 saveData()吗? 哪一个是安全的?

var waitGroup sync.WaitGroup

func main() {

    for i:=0; i<4; i++{
        waitGroup.Add(2)

        go doProcess_A(i)
        go doProcess_B(i)
    }
    waitGroup.Wait()
}

func doProcess_A(i int)  {
    // do process
    // the result will be stored in data variable
    data := "processed data-A as string"
    uniqueFileName := "file_A_"+strconv.Itoa(i)+".txt"
    saveData(uniqueFileName, data)

    waitGroup.Done()
}

func doProcess_B(i int) {
    // do some process
    // the result will be stored in data variable
    data := "processed data-B as string"
    uniqueFileName := "file_B_"+strconv.Itoa(i)+".txt"
    saveData(uniqueFileName, data)

    waitGroup.Done()
}

// write text file
func saveData(fileName ,dataStr string) {
    // file name will be unique.
    // there is no chance to be same file name
    err := ioutil.WriteFile("out/"+fileName, []byte(dataStr), 0644)
    if err != nil {
        panic(err)
    }
}

这里,当其他goroutine正在进行时,是否有一个goroutine等待磁盘文件操作?  或者,两个goroutine make有自己的saveData()副本?

1 个答案:

答案 0 :(得分:1)

Goroutines通常不会等待任何事情,除非您明确告诉他们或某个操作正在等待某个频道或其他阻止操作。在您的代码中,如果多个goroutine使用相同的文件名调用saveData()函数,则可能会出现意外结果的竞争条件。看起来两个goroutine正在写入不同的文件,因此只要文件名是唯一的,saveData操作在goroutine中就是安全的。使用go例程来调用saveData()是没有意义的,不要让你的生活变得不必要,只需直接在doProcess_X函数中调用它。

了解有关goroutines的更多信息,并确保在绝对必要时使用它。 - https://gobyexample.com/goroutines

  

注意:仅仅因为您正在编写Go应用程序并不意味着您   应该用goroutines乱丢它。阅读并理解它有什么问题   解决,以便知道使用它的最佳时间。

相关问题