I want to receive multiple values through 'receive' from a function that I called. Half of the code is as stated below:
-module(b).
-export([step13/3,step7/4,run/0]).
step13(P,Ev,Pid) ->
Lst = lists:nth(P,Ev),
receive
{E} ->
List = Lst ++ [E], L = lists:usort(List)
end,
Edgev = lists:sublist(Ev,P-1) ++ [L] ++ lists:nthtail(P,Ev),
Pid ! {Edgev}.
step7(0,_,_,_) ->
io:fwrite( "Step7 done");
step7(V,R,Ev,Parent) ->
case (V == R) of
true -> io:fwrite( "Root vertex, so leaving ~n");
false -> E = {V,V},
io:fwrite( "For the vertex is ~w ~n", [V] ),
io:fwrite( "New edge is ~w ~n", [E] ),
P = lists:nth(V,Parent),
Pid = spawn(b,step13,[P,Ev,self()]),
Pid ! {E}
end,
case (lists:member(V,Parent) == true) of
true ->
receive
{Edgev} ->
io:fwrite( "Ev now is ~w ~n", [Edgev] )
end;
false -> io:fwrite( "" )
end,
step7(V-1,R,Ev,Parent).
run() ->
V = 4,
Ev = [[{1,2},{1,3},{1,4}],[{2,1},{2,3}],[{3,1},{3,2},{3,4}],[{4,1},{4,3}]] ,
R = 1,
Parent = [0,1,4,1],
step7(V,R,Ev,Parent).
(Apologies for such a problem-oriented code instead of a generic one, the cleaning of the code was messing up one or the other things, I am explaining the code below)
Explanation:
So, initially, Ev is [[{1,2},{1,3},{1,4}],[{2,1},{2,3}],[{3,1},{3,2},{3,4}],[{4,1},{4,3}]] , R is 1(always fixed), V is 4, Parent is [0,1,4,1]
step7 function computes P as Vth element of Parent and calls step13 function, sends a tuple {V,V} to function step13 whenever V is not equal to R.(to be noted, step13 function was called by passing parameters Ev and P already)
step13 function does the following: It replaces the Pth index of Ev with received tuple {V,V}.
Now, here is the twist. Since there are duplicates in Parent, as we can see two 1, the value received is only for one of the 1, as step7 loop has already moved forward due to self recursive call step7(V-1,...).
What output I am getting is:
Ev now is [[{1,2},{1,3},{1,4},{2,2}],[{2,1},{2,3}],[{3,1},{3,2},{3,4}],[{4,1},{4,3}]]
Ev now is [[{1,2},{1,3},{1,4},{4,4}],[{2,1},{2,3}],[{3,1},{3,2},{3,4}],[{4,1},{4,3}]]
But what I want is:
Ev now is [[{1,2},{1,3},{1,4},{4,4}],[{2,1},{2,3}],[{3,1},{3,2},{3,4}],[{4,1},{4,3}]]
Ev now is [[{1,2},{1,3},{1,4}],[{2,1},{2,3}],[{3,1},{3,2},{3,4}],[{4,1},{4,3}]]
Ev now is [[{1,2},{1,3},{1,4},{2,2}],[{2,1},{2,3}],[{3,1},{3,2},{3,4}],[{4,1},{4,3}]]
Order might change, order is not necessary for me.
So, basically, I want to spawn, and from that spawned processes, I want to receive all the computed values in the original calling function.
I doubt how much clear have I been, Please ask me in comments, I will clarify the doubts. Thanks a lot, It has been some 1 week of me learning Erlang, I am still a newbie.
1条答案
按热度按时间x759pob21#
step7 is recursively called 5 times, with parameter V equal to 4,3,2,1,0.
at each call, you spawn the process step13 which will send back a message {Edgev}. Each step13 process will send back one and only one message, without any condition.
in step7, after the launch of the step13 process, you have two branches:
V == 4
, you receive the message from the step13 process, read it and remove it from the mailboxV == 3
, you receive the message from the step13 process but you don't read it so it stays in the mailbox.V == 2
V == 1
, you receive the message from the step13 process, read the mailbox and you get the message which was sent when V was equal to 3. the messages sent for V = 2 and 1 are still in the mailbox.V == 0
and your program exits, with the mailbox still full.I see the following problems in your code
The condition
(lists:member(V,Parent) == true)
is true only for V ==4 and V ==1. You can receive only 2 messages, but you expect 3.As you put the receive bloc under condition, you leave unwanted messages in the mailbox which will be read later in place of the expected ones (I don't understand what you are trying to do, but it is my guess) You should first receive the message and then perform the test, or, add a reference to the call, send it back in the return message and conditionally receive the message with this reference (in my opinion a bad solution since it does not empty the mailbox).
Step7 launches a process and wait for its answer. Unless the real code should process other data in between, it is useless. a simple call would be much more efficient.
[EDIT]
With your comment, and reading your code I made a first assumption that
If this is correct, I made a first modification in your code where step7 has 3 different steps
This is the logical order, but as often, the steps appear in reverse order in the code:
Or this version which looks cleaner to me