go - channel是否发送抢占点用于goroutine调度?

标签 go scheduling channel goroutine

根据我对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/

相关文章:

google-app-engine - 如何在 GAE Standard Go 中缩小到 0 个实例

go - 填充包含 slice 的结构

go - 您应该使用 protobuf 作为用于处理还是仅用于传输的数据类型?

linux - 实时Linux - 主线CPU屏蔽或PREEMPT_RT补丁集?

go - 隐藏发送到函数调用后面的 channel 是否安全

go - db.FirstOrCreate和db.Where()。FirstOrCreate()有何区别?

django - 在 django 应用程序中运行周期性任务的清晰分步过程

转到 channel : How to make this non-blocking?

go - 什么是 channel 缓冲区大小?

java - Java实现循环调度算法