我有两个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()副本?
答案 0 :(得分:1)
Goroutines通常不会等待任何事情,除非您明确告诉他们或某个操作正在等待某个频道或其他阻止操作。在您的代码中,如果多个goroutine使用相同的文件名调用saveData()
函数,则可能会出现意外结果的竞争条件。看起来两个goroutine正在写入不同的文件,因此只要文件名是唯一的,saveData
操作在goroutine中就是安全的。使用go例程来调用saveData()
是没有意义的,不要让你的生活变得不必要,只需直接在doProcess_X
函数中调用它。
了解有关goroutines的更多信息,并确保在绝对必要时使用它。 - https://gobyexample.com/goroutines
注意:仅仅因为您正在编写Go应用程序并不意味着您 应该用goroutines乱丢它。阅读并理解它有什么问题 解决,以便知道使用它的最佳时间。