如何让Haskell的TChan像Erlang的消息队列那样延迟消息?
考虑以下 Erlang 代码:
-module(testit).
-export([testit/0]).
testit() ->
Pid = spawn(fun testit_proc/0),
Pid ! final,
Pid ! one,
Pid ! two,
io:format("Root finished~n").
testit_proc() ->
receive
one -> io:format("One~n");
two -> io:format("Two~n")
end,
receive
one -> io:format("One~n");
two -> io:format("Two~n")
end,
receive
one -> io:format("One~n");
two -> io:format("Two~n");
final -> io:format("Final~n")
end,
io:format("Spawn finished~n").
输出为:
Root finished
One
Two
Final
Spawn finished
由于先前的接收模式与该消息不匹配,final
消息的处理本质上被推迟到最后一个接收块。
如何使用 Haskell 的 TChan 做到这一点?
Consider the following Erlang code:
-module(testit).
-export([testit/0]).
testit() ->
Pid = spawn(fun testit_proc/0),
Pid ! final,
Pid ! one,
Pid ! two,
io:format("Root finished~n").
testit_proc() ->
receive
one -> io:format("One~n");
two -> io:format("Two~n")
end,
receive
one -> io:format("One~n");
two -> io:format("Two~n")
end,
receive
one -> io:format("One~n");
two -> io:format("Two~n");
final -> io:format("Final~n")
end,
io:format("Spawn finished~n").
The output is:
Root finished
One
Two
Final
Spawn finished
The processing of the final
message is essentially deferred until the last receive block by virtue of the previous receive patterns not matching that message.
How do you do this with Haskell's TChan?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
你指的是Erlang的选择性接收功能。据我所知,Haskell 中的 STM 无可比拟。您的选择是重构代码以消除对其的需要(例如对可能接收的不同类型的信息使用单独的队列),或者在库中实现此功能。
选择性接收的语义是,除了传入消息队列之外,你还有一个延迟消息列表。在接收函数中,您需要首先扫描延迟列表以查找任何匹配的消息。如果消息匹配,则您可以将其从列表中删除并发送。如果没有匹配的延迟消息,则您需要等待收件箱中的消息。收到消息后,您检查它是否匹配。如果是,那么你就交付它;如果没有,则将其推入延迟列表并重复。
You're referring to Erlang's selective receive feature. As far as I know, STM in Haskell has no parallel to it. Your choices are to either refactor your code to remove the need for it (such as by using separate queues for the different types of information that may be received), or to implement this feature in a library.
The semantics of selective receive is that in addition to the incoming message queue, you also have a deferred message list. In the receive function, you need to first scan the deferred list for any matching messages. If a message matches, then you remove it from the list and deliver it. If no deferred messages match, then you need to wait for a message on the inbox. When a message is received, you check if it matches. If it does, then you deliver it; if not, then you push it to the deferred list and repeat.