-module(cooperate).
-compile(export_all).
producer(_Pid, 0) ->
done;
producer(Pid, N) ->
Pid ! {producer, N},
io:format("process ~p producing ~p~n", [self(), rand:uniform(N)]),
producer(Pid, N-1).
consumer() ->
receive
{producer,Pid} ->
timer:sleep(10),io:format("process ~p consuming ~p~n", [self(), Pid]),
consumer()
after 40 ->
stopping_terminus
end.
go() ->
Pid = spawn(cooperate, consumer, []),
spawn(cooperate, producer, [Pid, 3]).
Expecting:
process <x.xx.x> producing 2
process <x.xx.x> producing 100
process <x.xx.x> producing 555
process <x.xx.x> consuming 2
process <x.xx.x> consuming 100
process <x.xx.x> consuming 555
I successfully producing random number like 2, 100, 555. Now, I want to sent the message to consumer and print them out. By the code above, I can only print consuming 3,2,1 due to the producer(Pid, N-1).
This line:
sends the message
{producer, N}to the consumer. For example, the consumer will receive a message like{producer, 3}. You should be aware that in the consumer's receive statement:Pidwill not match a pid. Just because you name a variable Pid, does not mean that it will actually match a pid. A pid is its own type in erlang--it is not an integer. A pid looks like the following when printed in the shell:In your receive,
Pidwill actually matchN, andNis not a pid, ratherNis just an integer you pass as an argument. Do not name variablesPidthat do not actually match a pid.If you want the producer to send a random number to the consumer, how would you do that? Well, you need the producer to send a message like
{producer, SomeRandomNumber}. How do you do that?If the consumer needs to distinguish between the messages that contain
Nand the messages that containSomeRandomNumber, then you can send the messages like this:( or even
Pid ! {producer, N, SomeRandomNumber})Then in the consumer's receive statement, you can use matching to do different things for the different types of messages that the consumer receives: