[erlang-questions] How to fork/clone a process in Erlang?

60 views
Skip to first unread message

Xiao Jia

unread,
Sep 6, 2012, 11:02:00 AM9/6/12
to erlang-q...@erlang.org
Hi,

How can I fork/clone a process in Erlang, just as the fork in Unix?

I have searched a lot but just got nothing related to that. I suppose the usage may look like this:

case fork() of
  {parent, Pid} -> in_parent_process_now();
  {child, Pid} -> in_child_process_now();
end.

Any ideas?


Thanks,

Xiao Jia

Magnus Henoch

unread,
Sep 6, 2012, 11:10:32 AM9/6/12
to Xiao Jia, erlang-q...@erlang.org
There is nothing called "fork" in Erlang, but you can achieve pretty
much the same effect using 'spawn'. For example, your example could be
written as:

ParentPid = self(),
ChildPid = spawn(fun() -> in_child_process_now(ParentPid) end),
in_parent_process_now(ChildPid).

That is, the child process starts executing in the function passed to
'spawn', and the parent process keeps executing after the call to
'spawn'.

Hope this helps,
Magnus
_______________________________________________
erlang-questions mailing list
erlang-q...@erlang.org
http://erlang.org/mailman/listinfo/erlang-questions

Bengt Kleberg

unread,
Sep 6, 2012, 11:10:51 AM9/6/12
to erlang-q...@erlang.org
Greetings,

Suppose that you have a process running like this:
loop( State ) ->
receive
normal ->
New_state = new_state( State ),
loop( New_state )
_ -> ok
end.

You could add a forking like this:
loop( State ) ->
receive
normal ->
loop( State )
fork ->
spawn( fun() -> loop(State) end ),
loop( State )
_ -> ok
end.


bengt

Jesper Louis Andersen

unread,
Sep 6, 2012, 11:26:30 AM9/6/12
to bengt....@ericsson.com, erlang-q...@erlang.org
On Sep 6, 2012, at 5:10 PM, Bengt Kleberg <bengt....@ericsson.com> wrote:

> You could add a forking like this:

Do note, however that you don't get the copy-on-write semantics of the memory space, so this may not be a too good idea if State is quite large.

Xiao Jia

unread,
Sep 6, 2012, 9:31:32 PM9/6/12
to bengt....@ericsson.com, erlang-q...@erlang.org
Well, this approach can solve much of the problem.
Do you know if there's any approach which can clone the control flow as well as the states?

Of course in your example the control flow is cloned as you also loop in the spawn fun.
But what I want is a more general case. Take the following C code as an example.

f();
fork();
g();


Here the return value of fork() is ignored, so the next steps of both the parent and the child 
process are the same, which is to execute g(). Can I achieve this in Erlang?

2012/9/6 Bengt Kleberg <bengt....@ericsson.com>

Rich Neswold

unread,
Sep 6, 2012, 11:24:56 PM9/6/12
to Xiao Jia, erlang-q...@erlang.org
On Thu, Sep 6, 2012 at 8:31 PM, Xiao Jia <stf...@gmail.com> wrote:
> Of course in your example the control flow is cloned as you also loop in the
> spawn fun.
> But what I want is a more general case. Take the following C code as an
> example.
>
> f();
> fork();
> g();
>
> Here the return value of fork() is ignored, so the next steps of both the
> parent and the child
> process are the same, which is to execute g(). Can I achieve this in Erlang?

How about:

f(),
spawn(g),
g().

--
Rich

dmitry kolesnikov

unread,
Sep 6, 2012, 11:30:44 PM9/6/12
to Xiao Jia, erlang-q...@erlang.org
Hello,

At general level this is
f(),
spawn(fun g/0),
g()

The major concern here is supervision of forked processes, forking of gen_server and making OTP compliment application. 

Best Regards,
Dmitry >-|-|-*>

Xiao Jia

unread,
Sep 7, 2012, 12:10:35 AM9/7/12
to Rich Neswold, erlang-q...@erlang.org
Well, this is kind of different from what I'm thinking about. 

The function g() here is just a symbolic stuff, standing for the remaining control flows.

Suppose we want to implement a function, split(), which is to create two identical processes on invocation. We may use fork() inside split(). But from the user's perspective, he just calls split(). As we write the split() function, we cannot assume (actually we are unable to know) what is g().

2012/9/7 Rich Neswold <rich.n...@gmail.com>

Xiao Jia

unread,
Sep 7, 2012, 12:12:42 AM9/7/12
to dmkole...@gmail.com, Rich Neswold, erlang-q...@erlang.org
In other words, for ` f(); fork(); g(); ` , I wonder if it is possible to implement fork() just as is used here, i.e. without passing any parameters/arguments to fork().

2012/9/7 Xiao Jia <stf...@gmail.com>

Michael Turner

unread,
Sep 7, 2012, 12:16:18 AM9/7/12
to Xiao Jia, erlang-q...@erlang.org
On Fri, Sep 7, 2012 at 1:10 PM, Xiao Jia <stf...@gmail.com> wrote:
> Well, this is kind of different from what I'm thinking about.
>
> The function g() here is just a symbolic stuff, standing for the remaining
> control flows.
>
> Suppose we want to implement a function, split(), which is to create two
> identical processes on invocation.

I'm actually having a little trouble with that supposition. Even basic
UNIX split doesn't produce "identical processes" - for example, one
process has knowledge that it's the designated parent, the other that
it's the designated child.

What actual real-world problem are you trying to solve? Maybe Erlang
already does it in a better way.

-michael turner

> 2012/9/7 Rich Neswold <rich.n...@gmail.com>
>>
>> On Thu, Sep 6, 2012 at 8:31 PM, Xiao Jia <stf...@gmail.com> wrote:
>> > Of course in your example the control flow is cloned as you also loop in
>> > the
>> > spawn fun.
>> > But what I want is a more general case. Take the following C code as an
>> > example.
>> >
>> > f();
>> > fork();
>> > g();
>> >
>> > Here the return value of fork() is ignored, so the next steps of both
>> > the
>> > parent and the child
>> > process are the same, which is to execute g(). Can I achieve this in
>> > Erlang?
>>
>> How about:
>>
>> f(),
>> spawn(g),
>> g().
>>
>> --
>> Rich
>
>
>
> _______________________________________________
> erlang-questions mailing list
> erlang-q...@erlang.org
> http://erlang.org/mailman/listinfo/erlang-questions
>



--
Regards,
Michael Turner
Project Persephone
1-25-33 Takadanobaba
Shinjuku-ku Tokyo 169-0075
(+81) 90-5203-8682
tur...@projectpersephone.org
http://www.projectpersephone.org/

"Love does not consist in gazing at each other, but in looking outward
together in the same direction." -- Antoine de Saint-Exupéry

Xiao Jia

unread,
Sep 7, 2012, 12:21:48 AM9/7/12
to Michael Turner, erlang-q...@erlang.org


2012/9/7 Michael Turner <michael.eu...@gmail.com>

On Fri, Sep 7, 2012 at 1:10 PM, Xiao Jia <stf...@gmail.com> wrote:
> Well, this is kind of different from what I'm thinking about.
>
> The function g() here is just a symbolic stuff, standing for the remaining
> control flows.
>
> Suppose we want to implement a function, split(), which is to create two
> identical processes on invocation.

I'm actually having a little trouble with that supposition. Even basic
UNIX split doesn't produce "identical processes" - for example, one
process has knowledge that it's the designated parent, the other that
it's the designated child.

Then forget my "identical" thing :-)

What I meant is just to implement a split() without any knowledge of subsequent control flows.
 

What actual real-world problem are you trying to solve? Maybe Erlang
already does it in a better way.

I'm just playing around Erlang and wondering if it is possible to have this functionality.
It's kind of trying to dig out more stuffs inside Erlang, instead of using Erlang in the outside world. :-)

o...@cs.otago.ac.nz

unread,
Sep 7, 2012, 12:31:32 AM9/7/12
to Xiao Jia, erlang-q...@erlang.org
Erlang processes offer isolation like UNIX processes (as long
as you don't link in any C code, which could do arbitrary damage),
but they are more like threads. In fact they are more like threads
than threads are, being smaller, cheaper to create, and safe (no
more *having* to guess how big to make the stack and being at the
mercy of Cthulhu if you guess wrong!).

There isn't any 'fork()' to copy the current process because
*not* copying a whole lot of stuff you'll never want is part
of what Erlang processes are all about.

Having said this, it would be tedious rather than difficult to
provide a continuation-passing transformer for Erlang:

f(a, Y, b) -> Y;
f(X, Y, Z) -> P = g(X, Y), h(P, Z).

=>

f(a, Y, b, K) -> K(Y);
f(X, Y, Z, K) -> g(X, Y, fun (P) -> h(P, Z, K) end).

and then your fork() isn't that hard:

fork(K) -> K(spawn(fun () -> K(child) end)).

in the library for the continuation passing level, then
at the normal level
Which = fork()
would return 'child' in the child and the child's Pid in the parent.

But I am having a really hard time figuring out what you would
want this for. I've been using UNIX since October 1979 and I've
personally never had any use for a fork() that wasn't followed
by an exec(). I'm aware that people did this to create workers
in a process that listens for connections and then forks, but
these days people seem to prefer using threads for that.

So what is it you *really* want to do that makes fork()
seem like a good way to go?

Michael Turner

unread,
Sep 7, 2012, 1:26:07 AM9/7/12
to erlang-q...@erlang.org
"I'm just playing around Erlang and wondering if it is possible to
have this functionality."

Since Erlang is Turing-complete, the answer to any such question is
always going to be "yes."

-michael turner
--
Regards,
Michael Turner
Project Persephone
1-25-33 Takadanobaba
Shinjuku-ku Tokyo 169-0075
(+81) 90-5203-8682
tur...@projectpersephone.org
http://www.projectpersephone.org/

"Love does not consist in gazing at each other, but in looking outward
together in the same direction." -- Antoine de Saint-Exupéry
Reply all
Reply to author
Forward
0 new messages