My guess is that if you can find a way to pass a SIGQUIT signal to the terminal, and map that to Ctrl + d, that would would work. Not sure how to do that though.
FYI the Ctrl + \ keyboard shortcut is not specific to IEx/erl shell, I believe it is a behavior of the terminal emulator. You can use it to quit e.g. the Python shell, for example. So it’s handy to know outside of this specific context.
From iex you can do :erlang.exit(pid(0,0,0), :kill) which will unconditionally terminate the system but generate a crash dunp in the file erl_crash.dump. Don’t ask
Is it hardcoded somewhere that init is pid(0,0,0)? Or does it happen naturally that the mother of all processes just registers first and gets the zero-nth pid number?
The init module is preloaded into the BEAM and is the module that is automatically run by the BEAM when it starts its first process, the one that is <0.0.0>, calling the function init:boot(BootArgs) and the first thing it does is to register itself under the name init. It then traps exits. Note that although it a “special” process in how it is started and the module it runs it is actually just a normal Erlang process which is why you can kill it by sending it kill signal which is untrappable.
Actually all ALL processes in Erlang are equal and there are no special processes in any sense. Erlang is a very egalitarian in system in the sense that there are no special process and no special modules. All processes are equal and all modules are equal. You can kill or delete anything.
Hey ! Thank you. Yes I know all processes are treated equal, the “mother of all processes” was a joke, though it’s kinda true right ? If it’s the only process at the beginning, all other processes must have been spawned by this one or one of its spawns. Or the BEAM can also start other processes after boot?
Regarding the <0.0.0> process, it the pid number a simple counter that starts at zero, and the first process just gets that first number? Or is that pid enforced by other means? Spawning repeatedly generally yields increasing pid numbers so I have always assumed it was just a counter.
No, not really. It is really just a reference to the internal data defining the process. The only number which has any real significance is the first one.
Way way back in the the old days the 2nd number was an index into a process table and the 3rd number was the number of time this index had been used. This to keep pids unique. Now they don’t mean that, again you really can’t read much out of them.
The 1st number indicated whether the pid referenced a long process or a process on another node: 0 on the local; any other number another node. You couldn’t get any info from the number on which node it was, just not this one. That is still valid. So <0.0.0> says this is the pid of a local process, and we know it is the initial process.
Alright, thank you! It’s so nice to have you on the forum
(edit for below in order not to spam: yay! so indeed there is a counter increment, which makes sense given pids generally have growing middle numbers – thank you :))
I’m curious about the design decisions around process relationships in Erlang. Was there ever consideration for building parent-child relationships directly into processes at the VM level, similar to how POSIX maintains process trees with PPIDs?
I understand this can be achieved through supervisors and the OTP supervision tree, but I’m wondering if the core VM design ever included native parent-child tracking for all processes, or if the decision was made early on to keep the process model simpler and handle hierarchical relationships at the application level instead.
From the very beginning processes did not have built parent-child relationships. It did keep processes very simple and it allowed us to work on how to build systems. The ideas of how to structure systems developed as our understanding of the problem grew and what was needed to build reliable systems that could handle errors in the right way.
We were working together with another group in Ericsson who were looking at designing a new architecture and used Erlang for experimenting. As they were very knowledgeable about such systems they came back with comments and ideas about how they thought they should look and work and what Erlang needed. Out this grew error handling and what later became supervisors. They also actually developed the first system Ericsson using Erlang!
Note that these ideas evolved before OTP was built and most of the ideas that became formalised and described in OTP came from these ideas. For examples we had of course servers before we got OTP gen_server and we were managing processes and restarting them when necessary before we had supervisors.
One very good thing with OTP is that they “packaged” these things and bought order into the whole library and system structure. This is an ENORMOUS benefit when building systems. You cannot overate it.