我有一个代码,
Routine 1 { runtime.LockOSThread() print something send int to routine 2 runtime.UnlockOSThread } Routine 2 { runtime.LockOSThread() print something send int to routine 1 runtime.UnlockOSThread } main { go Routine1 go Routine2 }
我使用运行时锁定-解锁,因为我不希望例程1的打印与例程2混合使用。但是,执行上述代码后,其输出与没有锁定- 解锁的输出相同(意味着打印输出混合在一起)。谁能帮助我为什么这件事发生以及如何迫使这件事发生。
注意:我举了一个打印示例,但是有很多打印和发送事件。
如果您要 序列化 “打印某物”,例如,每个“打印某物”应自动执行,则只需对其进行 序列化即可 。
您可以用互斥锁包围“打印某些内容”。除非代码死锁因此而起作用,否则代码一定会死锁-而且肯定可以在一个非平凡的程序中轻松实现。
Go进行序列化的简单方法是使用通道。用例行程序收集应一起打印的所有内容。收集完打印单元后,将其通过通道发送给某些打印“代理”作为“打印作业”单元。该代理将仅接收其“任务”并自动打印每个任务。人们可以免费获得原子性,并且作为一项重要的奖励,在仅由非相互依赖的“打印单元”生成goroutine的简单情况下,代码不再容易死锁。
我的意思是:
func printer(tasks chan string) { for s := range tasks { fmt.Printf(s) } } func someAgentX(tasks chan string) { var printUnit string //... tasks <- printUnit //... } func main() { //... tasks := make(chan string, size) go printer(tasks) go someAgent1(tasks) //... go someAgentN(tasks) //... <- allDone close(tasks) }