阅读TChan会导致阻止还是轮询?

首先,一些背景。 我想要一个队列,我希望以两种不同模式之一进行操作。 在第一种模式下,我希望能够在队列中存在元素时检索元素,但如果没有元素则不能阻止元素。 在第二种模式下,我希望能够阻塞,直到队列中有一个元素。 (我知道我可以为每种模式使用专门的机制,但我想分解出一些常见的代码,因此如果我可以在两种操作模式中使用相同的机制,这将是最简单的。)

我可以使用Chan ,但根据文档我不应该使用isEmptyChan因为它由于潜在的死锁而被弃用。 这让我与TChantryReadTChan函数为我提供了第一种模式所需的内容(即,我可以检查一个元素是否存在,但没有阻塞),但我不确定readTChan是什么。 我的心理模型是, atomically块将继续重试,直到通道中存在元素,这意味着它将繁忙循环浪费CPU周期; 这与readChan (即非STM版本)不同(如果我理解正确的话)实际上会阻止线程的执行,直到元素可用为止,因为运行时线程调度程序可以理解MVars。

TChanChan一样,如果我使用readTChan那么运行时足够聪明,直到有一个值可用时才调度调用线程? 或者它会浪费大量的CPU周期不断轮询到一个值到达?


STM阻塞(通过retry )的行为就好像它立即重试事务,但实现更智能:由于STM随着事务的继续跟踪你读取的变量,它知道事务将以相同的方式运行因为这些变量具有相同的值。 所以当一个事务失败时,它会阻塞(不会真正重试),直到你使用的一个变量发生了变化。 在TChan的情况下,这意味着它会阻止,直到有人写到TChan

我推荐Simon Marlow的并发和并行Haskell的幻灯片,以便对STM进行很好的介绍(除其他外)。


你的思维模型具有正确的指称语义,但错过了STM所做的操作优化。 当一个事务在STM中重试时,它会阻塞,直到重试发生变化之前它读取的某个TVar 。 (是的, TChan是根据TVar实施的。)

所以执行一个事务的含义与交易不断重试的意义相同 - 但是如果事务内部事情没有发生变化,STM系统足够聪明,不会忙碌循环。

链接地址: http://www.djcxy.com/p/81455.html

上一篇: Does reading a TChan result in blocking or polling?

下一篇: Questions on STM implementations