一尘不染

与runtime.LockOSThread()和runtime.UnlockOSThread有关的问题

go

我有一个代码,

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混合使用。但是,执行上述代码后,其输出与没有锁定-
解锁的输出相同(意味着打印输出混合在一起)。谁能帮助我为什么这件事发生以及如何迫使这件事发生。

注意:我举了一个打印示例,但是有很多打印和发送事件。


阅读 296

收藏
2020-07-02

共1个答案

一尘不染

如果您要 序列化 “打印某物”,例如,每个“打印某物”应自动执行,则只需对其进行 序列化即可

您可以用互斥锁包围“打印某些内容”。除非代码死锁因此而起作用,否则代码一定会死锁-而且肯定可以在一个非平凡的程序中轻松实现。

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)
}
2020-07-02