通过频道传递的消息是否保证是非阻塞的?

Tob*_*ias 8 channel nonblocking go lock-free

为了评估go是否是音频/视频应用程序的可能选项,我想知道传入的消息是否满足任何非阻塞进度保证(无障碍,无锁或无等待).特别是,以下方案是相关的:

单生产者单一消费者:

两个线程使用共享通道进行通信.线程A只做异步发送,线程B只做异步接收.假设OS调度程序决定在"最坏的可能时刻"中断线程A一段无限的时间.线程B是否保证在有限数量的cpu周期内完成接收操作,或者是否有(理论上)线程A可以将信道置于线程B需要等待OS恢复线程A的状态?

多个生产者:

多个线程A1,A2,A3,......使用共享信道与一个或多个其他线程通信.线程Ai只进行异步发送.假设操作系统调度程序在"最坏的可能时刻"暂停A2,A3,...,无限期.线程A1是否仍然保证在有限数量的cpu周期内完成发送操作?进一步假设每个线程只想做一次发送.如果程序运行得足够长(使用"恶意"调度程序可能会使某些线程或中断匮乏并在"最糟糕的时刻"恢复线程),至少有一个发送保证成功吗?

我对这里的典型场景并不是那么感兴趣,而是最坏情况的保证.有关阻塞,锁定和无等待算法的更多详细信息,请参阅非阻塞算法(Wikipedia).

Eva*_*haw 9

正常发送和接收是按定义阻塞操作.您可以使用select语句执行非阻塞发送或接收:

select {
case ch <- msg:
default:
}
Run Code Online (Sandbox Code Playgroud)

(接收非常相似;只需替换案例陈述.)

发送仅在通道缓冲区中有空间时发生.否则,默认情况下运行.请注意,内部仍使用互斥锁(如果我正确读取代码).


Tob*_*ias 4

Go 内存模型不要求发送和接收是非阻塞的,并且当前运行 send实现锁定和 的通道recv。这意味着,例如,如果操作系统调度程序中断正在运行另一个 go 例程的另一个线程,而该线程在已获取通道锁的情况下尝试在同一通道上发送或接收,则可能会导致发送或接收 go 例程挨饿。 。

所以不幸的是答案是否定的:(

(除非有人使用非阻塞算法重新实现部分运行时)。