从我对Go调度器的理解来看,Go调度算法是部分先发制人:当 goroutine 调用函数或阻塞 I/O 时,会发生 goroutine 切换。
向通道发送消息时是否会发生 goroutine 切换?
// goroutine A
ch <- message
// some additional code without function calls
// goroutine B
message := <- ch
在上面的代码中,我想要后面的代码ch <- message
在切换到B之前执行A中的内容,这有保证吗?或者在 A 发送消息后 B 立即被安排ch
?
A 的通道发送可能会阻塞,此时它会交给调度程序,并且您无法保证 A 何时会再次收到控制权。它可能是在 B 中您感兴趣的代码之后。所以即使示例代码也有问题GOMAXPROCS=1
.
退后一步:何时发生抢占是一个实现细节;它在过去已经发生了变化(函数调用并不总是有机会抢占),并且将来可能会发生变化。就记忆模型,如果您的程序依赖于有关代码执行时间的事实,而这些事实今天碰巧是正确的,但不能保证,那么您的程序就是不正确的。如果您想阻止 B 中的某些代码运行,直到 A 执行某些操作,您需要找到一种方法来使用通道或sync
基元。
正如用户 JimB 所指出的,您甚至不需要考虑抢占就会遇到示例代码的问题。 A和B可以同时运行在不同的CPU核心上,并且B中接收后的代码可以在A中发送后的代码运行的同时运行。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)