我有三个这样的并发例程,
func Routine1() {
Print (value a, value b, value c)
Print (value a, value b, value c)
Print (value a, value b, value c)
}
func Routine2() {
Print (value e, value f, value g)
Print (value e, value f, value g)
Print (value e, value f, value g)
}
func Routine3() {
Print (value x, value y, value z)
Print (value x, value y, value z)
Print (value x, value y, value z)
}
func main() {
go Routine1(command12, response12, command13, response13)
go Routine2(command12, response12, command23, response23)
Routine3(command13, response13, command23, response23)
}
现在我面临的问题是,有时会发生这样的情况,由于三个并发例程的结果,有时print语句没有正确执行意味着不打印整体,有一些东西被另一个打印插入。例如,例程1的Print(值a,值b,值c)给出输出,如值a,值b,值g,其中值g由例程2插入。任何人都可以建议我,我该如何阻止它?我尝试过sync-mutex程序。但是可能是因为我的代码太长而且我可能无法以正确的方式解锁 - 因此它会给出死锁错误。任何人都可以建议我如何以简单的方式或风险较低的sync-mutex程序实现这些。
有关我的这个问题的更多信息可以找到here。
答案 0 :(得分:6)
按照您的描述进行打印不是原子操作。不要使用互斥锁,请尝试使用Go方式。将通道传递到每个接受字符串的goroutine。每次要打印时,只需将字符串发送到该频道即可。
单独的goroutine只会从该频道读取并打印出来的任何内容。这样就不需要锁了。
package main
import (
"fmt"
"sync"
)
func main() {
var wg sync.WaitGroup
wg.Add(2) // 2 routines we need to wait for.
stdout := make(chan string)
go routine1(&wg, stdout)
go routine2(&wg, stdout)
go printfunc(stdout)
wg.Wait()
close(stdout)
}
func routine1(wg *sync.WaitGroup, stdout chan<- string) {
defer wg.Done()
stdout <- "first print from 1"
// do stuff
stdout <- "second print from 1"
}
func routine2(wg *sync.WaitGroup, stdout chan<- string) {
defer wg.Done()
stdout <- "first print from 2"
// do stuff
stdout <- "second print from 2"
}
func printfunc(stdout <-chan string) {
for {
select {
case str := <- stdout:
fmt.Println(str)
}
}
}