Fork
From Rosetta Code
Contents |
[edit] 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.
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
)
Output:
This is new process This is the original process
[edit] AutoHotkey
instancenum = %1%+1
MsgBox, 4, Fork Process, %instancenum% number: run another?
IfMsgBox, Yes
Run, %A_ScriptFullName% %instancenum%
ExitApp
[edit] C
Library: POSIX
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int
main()
{
pid_t pid;
if ((pid = fork()) == 0) {
printf("child process\n");
} else if (pid > 0) {
printf("parent process\n");
} else {
perror("fork");
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
[edit] C++
Translation of: C
Library: POSIX
#include<iostream>
#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;
}
[edit] Clojure
In Clojure, a computation can be done asynchronously, with Clojure managing the thread pool, by creating an agent with an initial step. Computational requests are sent using 'send', and the agent can be dereferenced to obtain its current state. To make sure the computation has finished, await can be used, or await-for for a bounded wait.
user=> (def child (agent (iterate inc 1)))
#'user/child
user=> (send child #(reduce + (take 1000 %)))
#<Agent@215f7107: 500500>
user=> (await child)
nil
user=> @child
500500
[edit] Common Lisp
There's not a standard way to fork, but some implementations have built-in bindings for POSIX fork.
Translation of: C
Works with: SBCL
(let ((pid (sb-posix:fork)))
(cond
((zerop pid) (write-line "This is the new process."))
((plusp pid) (write-line "This is the original process."))
(t (error "Something went wrong while forking."))))
[edit] 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().
[edit] Factor
This works only in the terminal, if used from the UI the child process won't print.
USING: unix unix.process ;
[ "Hello form child" print flush 0 _exit ] [ drop "Hi from parent" print flush ] with-fork
[edit] Haskell
import System.Posix.Process
main = do
forkProcess (putStrLn "This is the new process")
putStrLn "This is the original process"
[edit] 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";;
[edit] Oz
Mozart's support for distributed programming is quite unique. We can send code accross the network and share data by lexical scoping. It doesn't matter whether we create the process on the local machine (as in this example) or on some remote computer as long as we have ssh access (or some similar method) and Mozart is installed.
declare
ParentVar1 = "parent data"
ParentVar2
functor RemoteCode
export
result:Result
import QTk at 'x-oz://system/wp/QTk.ozf'
define
Result
%% Show a simple window. When it is closed by the user, set Result.
Window =
{QTk.build
td(action:proc {$} Result = 42 end %% on close
label(text:"In child process: "#ParentVar1))} %% read parent process variable
{Window show}
!ParentVar2 = childData %% write to parent process variable
{Wait Result}
end
%% create a new process on the same machine
RM = {New Remote.manager init(host:localhost)}
%% execute the code encapsulated in the given functor
RemoteModule = {RM apply(RemoteCode $)}
in
%% retrieve data from child process
{Show RemoteModule.result} %% prints 42
%% exit child process
{RM close}
{Show ParentVar2} %% print "childData"
[edit] Perl
Works with: Perl version 5.x In the child code, you may have to re-open database handles and such.
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);
}
Obviously you could do a Fork in a lot less lines, but this code covers all the bases
[edit] PHP
Translation of: C
<?php
$pid = pcntl_fork();
if ($pid == 0)
echo "This is the new process\n";
else if ($pid > 0)
echo "This is the original process\n";
else
echo "ERROR: Something went wrong\n";
?>
[edit] PicoLisp
(unless (fork) # In child process
(println *Pid) # Print the child's PID
(bye) ) # and terminate
[edit] Pop11
lvars ress;
if sys_fork(false) ->> ress then
;;; parent
printf(ress, 'Child pid = %p\n');
else
printf('In child\n');
endif;
[edit] Python
Works with: Python version 2.5
import os
pid = os.fork()
if pid > 0:
# parent code
else:
# child code
[edit] Ruby
pid = fork
if pid
# parent code
else
# child code
end
or
fork do
# child code
end
# parent code
[edit] 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).
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]]
].
[edit] 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.
[edit] Standard ML
case Posix.Process.fork () of
SOME pid => print "This is the original process\n"
| NONE => print "This is the new process\n";
[edit] 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).
The Library: Expectpackage includes a fork. So does the Library: TclXpackage.
Example:
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."
}
}
}
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.
Note that fork is only supported at all on unthreaded builds of Tcl. This is because the POSIX threads library does not sit well with the fork() system call.
[edit] Toka
needs shell
getpid is-data PID
[ fork getpid PID = [ ." Child PID: " . cr ] [ ." In child\n" ] ifTrueFalse ] invoke
[edit] 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")







