根据我对Go调度器的理解,Go调度算法是partially preemptive : 当 goroutine 正在调用函数或阻塞 I/O 时,会发生 goroutine 切换。
向 channel 发送消息时是否会发生 goroutine 切换?
// goroutine A
ch <- message
// some additional code without function calls
// goroutine B
message := <- ch
在上面的代码中,我想要ch <- message
之后的代码in A 在切换到 B 之前执行,这有保证吗?还是在 A 在 ch
上发送消息后立即安排 B ?
最佳答案
A 的 channel 发送可以阻塞,此时它会屈服于调度程序,并且您无法保证 A 何时会再次获得控制权。它可能在 B 中您感兴趣的代码之后。因此即使使用 GOMAXPROCS=1
,示例代码也有问题。
退后一步:何时发生抢占是一个实现细节;它在过去发生过变化(并不总是有机会抢占函数调用)并且将来可能会发生变化。在memory model方面,如果您的程序依赖于代码何时执行的事实,而这些事实在今天恰好是正确的但不能保证,那么您的程序就是不正确的。如果您想阻止 B 中的某些代码运行,直到 A 执行某些操作,您需要找到一种使用 channel 或 sync
基元进行安排的方法。
正如用户 JimB 所说,您甚至不需要考虑抢占就会遇到示例代码的问题。 A 和 B 可以同时运行在不同的 CPU 内核上,并且 B 中接收后的代码可以在 A 中发送后的代码运行时运行。
关于go - channel是否发送抢占点用于goroutine调度?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34192352/