- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我希望有人能帮助我理解为什么下面的代码会生成下面的输出。代码来自 Simon Marlow 书中的并发章节(链接如下)。
根据对各种功能的描述,我假设第二个 putMVar
鉴于 (i) 两个 putMVar
函数是同一线程的一部分,并且 (ii) 已经分配了一个值。显然情况并非如此。很高兴了解这里“幕后”发生的事情。
(注意:这本书使用 do
表示法,但我更喜欢 >>=
表示法,因为我认为它更直接 - 因此下面的代码版本。)
Link to book
import Control.Concurrent
main :: IO ()
main = newEmptyMVar >>=
\m -> forkIO (putMVar m 'x' >>= \_ -> putMVar m 'y') >>=
\_ -> takeMVar m >>=
print >>=
\_ -> takeMVar m >>=
print
% ./mvar2
'x'
'y'
最佳答案
为了我自己,这里是 do
中的代码符号。
main :: IO ()
main = do
m <- newEmptyMVar
forkIO $ do
putMVar m 'x'
putMVar m 'y'
x <- takeMVar m
print x
y <- takeMVar m
print y
MVar
调用
m
.
MVar
语义是这样的:
MVar
可以是空的或满的。如果您想阅读
MVar
它是空的,那么你必须等到它变满。如果您
readMVar
那么您将简单地解析存储在完整
MVar
中的值你尽快做。如果您
takeMVar
然后您将解析该值,然后在阅读后立即将其清空。
putMVar
将新值放入
MVar
如果
MVar
是空的。如果它已满,那么您必须等到它变空。
MVar
的空虚和满度上变得同步。 .
BG
和主线程
MN
.
t = 1 : MN makes a new, empty MVar called 'm'
t = 2 : BG puts 'x' in 'm' making it full
t = 3 : BG attempts to put 'y' in 'm', but since 'm' is full BG blocks
t = 4 : MN attempts to read 'm' and succeeds as it is full
t = 5 : BG now places 'y' into the newly empty 'm'
t = 6 : BG dies
t = 6 : MN prints the value it previously read
t = 7 : MN attempts to read 'm' and succeeds as it is full
t = 8 : MN prints the value it previously read
t = 9 : MN dies
BG
阻止在
MVar
中添加更多值比什么
MN
可以阅读。这会产生您观察到的打印语义。
关于haskell - `forkIO` 和 `putMVar` : what's going on under the hood?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26856108/
我是 Python 的新手,在理解如何str(123) 或 int('123') 函数有效。 我试图检查 builtins.py,但其中有一些我无法理解的函数和方法。都是关于二进制转换的吗? 作为一个
你们都知道将依赖项放入 pom.xml 文件并运行“mvn clean install”的过程。当此命令运行时,依赖项的 jar 文件将下载到 .m2 存储库。 当我们使用 IntelliJ 和运行/
当我们使用锁对象时会发生什么?我知道运行时使用了 monitor.Enter 和 Exit 方法。但幕后到底发生了什么?为什么只有引用类型用于锁定?实现加锁的对象虽然变了,为什么还能保证线程安全? 在
共享首选项作为键值对存储在 xml 文件中。这是事实。我还没有找到关于击球手的任何文档,但是......当试图找到并加载某个键的值时,它实际上是如何在 xml 中查找键的?它是将整个 xml 文件加载
关闭。这个问题是off-topic .它目前不接受答案。 想改进这个问题吗? Update the question所以它是on-topic用于堆栈溢出。 关闭 10 年前。 Improve thi
我了解在 MATLAB 等语言中使用矢量化如何通过消除维护循环变量的开销来加速代码,但矢量化实际上是如何在汇编/机器代码中发生的?我的意思是在某处仍然必须有一个循环,对吧? 最佳答案 Matlab 的
我想知道银行交易是如何运作的。很难找到一些至少可以接受的解释。我不是指一些不那么严肃的企业的基本分布式事务算法。 那么银行应该采取什么样的措施来保持一致性,做到一分钱不漏。 国际交易,银行之间的交易呢
我还在学习 C++。我试图以相当循序渐进的方式了解评估是如何进行的。所以使用这个简单的例子,一个表达式语句: 整数 x = 8 * 5 - 5; 这就是我相信发生的事情。请告诉我我离标准还有多远: 操
我有一个内部应用程序(不适用于 iPhone 商店分发,因此不受 Apple 批准)需要在运行时绑定(bind)一些 TCP 和 UDP 套接字。 在测试时,我注意到我绑定(bind)的套接字有一些奇
我不熟悉错误/异常处理。当异常被捕获 和抛出 时,“幕后”发生了什么? 即在 try-catch block 中捕获异常然后抛出它有什么意义? 例如: try { //Stuff
读完这个问题:What are the problems of a zero-terminated string that length-prefixed strings overcome?我开始怀疑
我已经在我的博客中下载并应用了 red hood 模板(Red Hood)。但是我发现 slider 不会随计时器自动滑动。这是 Red hood slider 代码..
这是 make-counter 过程和对它的调用 (define make-counter (let ((glob 0)) (lambda () (le
.NET、Java 和其他各种语言的高级数据库 API 通常提供称为准备语句和参数绑定(bind)的技术,而不是向数据库服务器发送纯文本命令。我想知道的是当您执行这样的语句时会发生什么: SqlCom
像这样一个简单的程序: int main(void) { char p; char *q; q = &p; return 0; } &p是如何确定的?编译器是预先计算所
我想知道关于 Unix(特别是 Linux)上的 C++ 多线程“幕后”发生了什么——特别是操作系统和信号量等的参与。 我已经进行了初步的谷歌搜索,但没有出现异常。 有人可以描述或指出可以提供帮助的好
我希望有人能帮助我理解为什么下面的代码会生成下面的输出。代码来自 Simon Marlow 书中的并发章节(链接如下)。 根据对各种功能的描述,我假设第二个 putMVar鉴于 (i) 两个 putM
perl 中的基本类型与大多数语言不同,类型为标量、数组、哈希(但显然不是子例程,&,我猜这实际上只是带有语法糖的标量引用)。最奇怪的是,最常见的数据类型:int、boolean、char、strin
刚刚开始将 Hood.ie 用于网络应用程序,但是在获取一些数据时遇到问题。 我想获取数据,然后简单地执行类似的操作 hoodie.store.find('teammember', theId).fi
来自 React Native 文档: XMLHttpRequest API is implemented on-top of iOS networking apis. 另外(来自Github iss
我是一名优秀的程序员,十分优秀!