this is my question:
I have a group of gen_servers which are started without name and that during the init function use pg2:join(group, self()). Until here it works fine.
I used in terminate function pg2:leave(group, self()). but if I kill one of the pids retrieved using pg2:get_members(group). the pid of the killed process in still in the list given by pg2:get_members(group).
I tried to use the leave function by mean of a gen_server call and in this case it works fine.
Can you tell me what is wrong?
Thanks
it was a problem on erlang version.
Related
I would like to know when the user from a command line presses control-c so I can save some stuff.
How do I do this? I've looked but haven't really seen anything.
Note: I'm somewhat familiar with lua, but I'm no expert. I mostly use lua to use the library Torch (http://torch.ch/)
Implementing a SIGINT handler is straightforward using the excellent luaposix library:
local signal = require("posix.signal")
signal.signal(signal.SIGINT, function(signum)
io.write("\n")
-- put code to save some stuff here
os.exit(128 + signum)
end)
Refer to the posix.signal module's API documentation for more information.
There exists io libraries that support this.
I know zmq and libuv
Libuv example with lluv binding - https://github.com/moteus/lua-lluv/blob/master/examples/sig.lua
ZeroMQ return EINTR from poll function when user press Ctrl-C
But I do not handle thi byself
windows : SetConsoleCtrlHandler
linux : signal
There are two behaviors of the signal which are undesirable, which will cause complexities in the code.
Program termination
Broken IO
The first behavior can be caught and remembered in a C program by using SetConsoleCtrlHandler/signal. This will allow your function to be called, and you can remember that the system needs to shutdown. Then at some point in the lua code you see it has happened (call to check), and perform your tidy up and shutdown.
The second behavior, is that a blocking operation (read/write) will be cancelled by the signal, and the operation will be unfinished. That would need to be checked at each IO event, and then re-started, or cancelled as appropriate.
require('sys')
sys.catch_ctrl_c()
I use this to catch the exit from cli.
If I have a process A that makes call to a function in process B (procB:func().), and func() generates an error during execution. Process B would terminate, but what about process A? Consider the following in process A:
Case 1:
{ok, Reply} = procB:func().
Case 2:
procB:func().
Will process A terminate in both cases? Or just in case 1 because of mismatch? Please note that the two processes are not linked.
Thanks in advance!
There is no such thing as calling a function in another process, you can send a message to a process that it then may choose to call a function based on message content.
gen_servers work this way, you send a message to the gen_server, and it does a match on the message and chooses if it should invoke call/cast/info/terminate functions.
Assuming you are really talking about sending a message from A to B and B decides to exit, it's all about if process A is linked/monitoring process B.
If you monitor B, you are sent a message saying that B went down and the reason.
If you are linked to B, I believe the rule is you are killed if B died with a status other than 'normal'
A could also have set the flag trap_exit, which means that even if linked and B dies, A is sent a message that he should die and you get to interact with that message (ie: you may restart B, if you choose)
learn you some erlang has a good tutorial on how this works.
You are not able to call function in another process. That is the beauty of Erlang: all communication between processes is via message passing. People sometimes confuse modules with processes. I even wrote article about it.
For example process A:
spawns process B
sends message which is for example tuple {fun_to_call, Args, self()} (you need the self() to know, where to respond
waits for reply using receive
Process B:
immediately after start waits for message
when receives message, does some computation and sends response back
This looks like a lot of boilerplate, so this exact pattern is abstracted in gen_server
When I need to create a process,I will use the customary spawn bif.But there is one more bif spawn_link that is often used to do the same thing.
So basically when should one use spawn and spawn_link?
Doing spawn and then link manually is equivalent in operation to spawn_link, but it is not equivalent in time; in particular it is not atomic (as in, two independent operations, not a single, indivisible one). If you spawn a process and it dies in its initialization (whatever your start or init functions do) then it might die before the call to link completes, and the linked process will never get notified that the process died since it died before it was linked. Oops!
From Joe Armstrong's Programming Erlang Ch.13 "Why Spawning and Linking Must be an Atomic Operation":
Once upon a time Erlang had two primitives, spawn and link, and spawn_link(Mod, Func, Args) was defined like this:
spawn_link(Mod, Func, Args) ->
Pid = spawn(Mod, Func, Args),
link(Pid),
Pid.
Then an obscure bug occurred. The spawned process died before the link statement was called, so the process died but no error signal was generated. This bug took a long time to find. To fix this, spawn_link was added as an atomic operation. Even simple-looking programs can be tricky when concurrency is involved.
spawn just spawns a new process.
spawn_link spawns a new process and automatically creates a link between the calling process and the new process. So it can be implemented as:
my_spawn_link(Module, Function, Args) ->
Pid = spawn(Module, Function, Args),
link(Pid),
Pid.
I am new to erlang.
I wonder if it is possible to interrupt a processor in erlang. Assume we have processor x executing a function f1() that takes a long time to execute. I would like to find an efficient way to interrupt the processor x to execute function f2() and after the execution of f2() it goes back to executing f1() from it was interrupted.
One way of doing this (although not exactly what I want) is to let f1() be executed by a processor (name it, f1_proc), while the creator of f1_proc wait for messages such as [interrupt, f1_terminated, etc ..] where if interrupt is received f2() is executed.
However, this is not exactly what I want. What if f2() depends on f1() ? in this case, f1() is paused, f2() is executed and then f1() should start from it stopped. I know we can terminate a process, but can we pause them ?
The answer to your question is no, this can't be done. There is no way to pause a process from the "outside" without any hook (e.g. receive clause) inside the process.
I think your question title (processor) is a bit misleading considering you are trying to work with erlang processes.
You should trying working with erlang hibernate command.
Directly from the above doc link:
Puts the calling process into a wait state where its memory allocation
has been reduced as much as possible, which is useful if the process
does not expect to receive any messages in the near future.
Using timers and message passing between processes you can force your workflow.
i.e. pausing one if it takes too much time, while other continues doing it work.
Though your use case is not so clear in the question, you also can have both (infact more) processes working in parallel without having to wait for one another, and also getting notified once a process has finished it's job.
One way to do it is to simply start both functions in different processes. When f2() is dependent on a result from f1(), it receives a message with the needed data. When f1() is done calculating that data, it sends it to the f2() process.
If f2() reaches the receive clause too early, it will automatically pause and wait until the message arrives (hence letting f1() continue its work). If f1(), however, is done first, it will carry on with it's other tasks until preempted automatically by the Erlang process scheduler.
You can also make f1() pause by letting it wait for a message from f2() as well. In that case, make sure that f1() waits AFTER it has sent its message to avoid deadlocks.
Example:
f1(F2Pid) ->
Data = ...,
F2Pid ! {f1data, Data},
... continue other tasks ....
f2() ->
... do some work ...,
Data = receive
{f1data, F1Data} -> F1Data
end,
... do some work with Data ....
main() ->
F2Pid = spawn_link(?MODULE, f2, []),
f1(F2Pid).
This message passing is fundamental to the Erlang programming model. You donät need to invent synchronisation or locks. Just receive a message and Erlang will make sure you get that message (and that message only).
I don't know how you are learning Erlang, but I recommend the book Erlang Programming by Cesarini & Thompson (O'Reilly). The book covers, in great detail and with good examples, all you need to know about message passing and concurrency.
This could be a very basic question but is Erlang capable of calling a method on another prcoess and wait for it to repond back with some object type without sleeping threads?
Well, if you're waiting for an answer, the calling process will have to sleep eventually… But that's no big deal.
While processes are stuck on the receive loop, other processes can work. In fact, it's not uncommon to have thousands of processes just waiting for messages. And since Erlang processes are not true OS threads, they're very lightweight so the performance loss is minimal.
In fact, the way sleep is implemented looks like:
sleep(Milliseconds) ->
receive
% Intentionally left empty
after Milliseconds -> ok
end.
Yes, it is possible to peek into the mailbox if that is what you mean. Say we have sent a message to another process and now we want to see if the other process has sent something back to us. But we don't want to block on the receive:
receive
Pattern -> Body;
Pattern2 -> Body2
after 0 ->
AfterBody
end
will try to match against the Pattern and Pattern2 in the mailbox. If none matches, it will immediately time out and go to AfterBody. This allows you to implement a non-blocking peek into the mailbox.
If the process is a gen_server the same thing can be had by playing with the internal state and the Timeout setting when a callback returns to the gen_server's control. You can set a Timeout of 0 to achieve this.
What am getting from the question is that we are talking of Synchronous Message Passing. YES ! Erlang can do this perfectly well, its the most basic way of handling concurrency in Erlang. Consider this below:
rpc(Request, To)->
MySelf = self(),
To ! {MySelf,Request},
receive
{To,Reply} -> Reply
after timer:seconds(5) -> erlang:exit({error,timedout})
end.
The code above shows that a processes sends a message to another and immediately goes into waiting (for a reply) without having to sleep. If it does not get a reply within 5 seconds, it will exit.