10

次の 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 の TChannel でこれを行うにはどうすればよいですか?

4

1 に答える 1

3

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.

于 2010-03-03T19:48:40.837 に答える