【问题标题】:is it safe to call a method from two different goroutine at same time?同时从两个不同的 goroutine 调用方法是否安全?
【发布时间】:2018-04-26 18:30:57
【问题描述】:

我有两个 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 制作了自己的 saveData() 副本?

【问题讨论】:

  • 我不确定您所说的“SaveData() 的副本”是什么意思,但 saveData 不使用任何共享值,因此并发调用它没有什么不安全的。

标签: go concurrency goroutine


【解决方案1】:

Goroutine 通常不会等待任何事情,除非您明确告诉它们,或者某个操作正在等待通道或其他阻塞操作。在您的代码中,如果多个 goroutine 使用相同的文件名调用 saveData() 函数,则可能会出现不希望的结果的竞争条件。看起来这两个 goroutine 正在写入不同的文件,因此只要文件名是唯一的,saveData 操作在 goroutine 中将是安全的。使用 goroutine 调用 saveData() 是没有意义的,不要不必要地复杂化你的生活,直接在 doProcess_X 函数中调用即可。

阅读有关 goroutine 的更多信息,并确保您在绝对必要的地方使用它。 - https://gobyexample.com/goroutines

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

【讨论】:

    猜你喜欢
    • 2011-08-13
    • 1970-01-01
    • 2016-08-13
    • 2018-03-12
    • 1970-01-01
    • 2011-03-10
    • 1970-01-01
    • 2017-07-15
    • 1970-01-01
    相关资源
    最近更新 更多