Fork

From Rosetta Code
Revision as of 06:25, 15 June 2009 by rosettacode>Tinku99 (omit autohotkey: fork not available on windows)
Task
Fork
You are encouraged to solve this task according to the task description, using any language you may know.

In this task, the goal is to spawn a new process which can run simultaneously with, and independently of, the original parent process.

ALGOL 68

Translation of: C
Works with: ALGOL 68G version Any - tested with release mk15-0.8b.fc9 - "fork" is not part of the standard's prelude.

<lang> main: (

 INT pid;
 IF (pid:=fork)=0 THEN
   print("This is new process")
 ELIF pid>0 THEN
   print("This is the original process")
 ELSE
   print("ERROR: Something went wrong")
 FI

) </lang> Output:

This is new process
This is the original process

C

Works with: gcc
Library: POSIX

<lang c>#include<stdio.h>

  1. include<unistd.h>

int main(void) {

 pid_t pid;
 if((pid=fork())==0) {
   printf("This is new process\n");
 } else if(pid>0) {
   printf("This is the original process\n");
 } else {
   printf("ERROR: Something went wrong\n");
 }
 return 0;

}</lang>

C++

Translation of: C
Library: POSIX

<lang cpp>

  1. include<iostream>
  2. include<unistd.h>

int main() {

 pid_t pid = fork();
 if (pid == 0)
 {
   std::cout << "This is the new process\n";
 }
 else if (pid > 0)
 {
   std::cout << "This is the original process\n";
 }
 else
 {
   std::cerr << "ERROR: Something went wrong\n";
 }
 return 0;

} </lang>

Erlang

-module(fork).
-export([start/0]).

start() ->
    spawn(fork,child,[]),
    io:format("This is the original process~n").

child() ->
    io:format("This is the new process~n").

Then you can compile your code and execute it:

c(fork).
fork:start().

OCaml

<lang ocaml>#load "unix.cma";; let pid = Unix.fork ();; if pid > 0 then

 print_endline "This is the original process"

else

 print_endline "This is the new process";;</lang>

Perl

Works with: Perl version 5.x

In the child code, you may have to re-open database handles and such.

<lang perl>FORK: if ($pid = fork()) {

   # parent code

} elsif (defined($pid)) {

   setsid; # tells apache to let go of this process and let it run solo
   # disconnect ourselves from input, output, and errors
   close(STDOUT);
   close(STDIN);
   close(STDERR);    
   # re-open to /dev/null to prevent irrelevant warn messages.
   open(STDOUT, '>/dev/null');
   open(STDIN, '>/dev/null');
   open(STDERR, '>>/home/virtual/logs/err.log');
   
   # child code
   
   exit; # important to exit

} elsif($! =~ /emporar/){

   warn '[' . localtime() . "] Failed to Fork - Will try again in 10 seconds.\n";
   sleep(10);
   goto FORK;

} else {

   warn '[' . localtime() . "] Unable to fork - $!";
   exit(0);

}</lang>

Obviously you could do a Fork in a lot less lines, but this code covers all the bases

Pop11

lvars ress;
if sys_fork(false) ->> ress then
   ;;; parent
   printf(ress, 'Child pid = %p\n');
else
   printf('In child\n');
endif;

Python

Works with: Python version 2.5

<lang python>import os

pid = os.fork() if pid > 0:

# parent code

else:

# child code</lang>

Ruby

<lang ruby>pid = fork if pid

# parent code

else

# child code

end</lang> or <lang ruby>fork do

 # child code

end

  1. parent code</lang>

Slate

The following built-in method uses the cloneSystem primitive (which calls fork()) to fork code. The parent and the child both get a socket from a socketpair which they can use to communicate. The cloneSystem is currently unimplemented on windows (since there isn't a fork() system call).

<lang slate> p@(Process traits) forkAndDo: b [ | ret |

 ret: (lobby cloneSystem).
 ret first ifTrue: [p pipes addLast: ret second. ret second]
           ifFalse: [[p pipes clear. p pipes addLast: ret second. b applyWith: ret second] ensure: [lobby quit]]

]. </lang>

Smalltalk

<lang smalltalk>'Here I am' displayNl. |a| a := [

 (Delay forSeconds: 2) wait . 
 1 to: 100 do: [ :i | i displayNl ]

] fork. 'Child will start after 2 seconds' displayNl. "wait to avoid terminating first the parent;

a better way should use semaphores"

(Delay forSeconds: 10) wait.</lang>

Standard ML

<lang sml>case Posix.Process.fork () of

  SOME pid => print "This is the original process\n"
| NONE     => print "This is the new process\n";

</lang>

Tcl

(from the Tcl Wiki)

Fork is one of the primitives used for process creation in Unixy systems. It creates a copy of the process that calls it, and the only difference in internal state between the original and the copy is in the return value from the fork call (0 in the copy, but the pid of the copy in the parent).

Expect includes a fork. So does TclX.

Example:

<lang tcl> package require Expect

   # or
   package require Tclx
   for {set i 0} {$i < 100} {incr i} {

set pid [fork] switch $pid { -1 { puts "Fork attempt #$i failed." } 0 { puts "I am child process #$i." exit } default { puts "The parent just spawned child process #$i." } }

   }</lang>

In most cases though, one is not interested in spawning a copy of the process one already has, but rather wants a different process. When using POSIX APIs, this has to be done by first forking and then having the child use the exec system call to replace itself with a different program. The Tcl exec command does this fork&exec combination — in part because non-Unix OSs typicallly don't have "make a copy of parent process" as an intermediate step when spawning new processes.

Toka

needs shell
getpid is-data PID
[ fork getpid PID = [ ." Child PID: " . cr ] [ ." In child\n" ] ifTrueFalse ] invoke

UnixPipes

Demonstrating a subshell getting forked, and running concurrently with the original process

(echo "Process 1" >&2 ;sleep 5; echo "1 done" ) | (echo "Process 2";cat;echo "2 done")