This commit is contained in:
Ingy döt Net 2013-04-10 21:29:02 -07:00
parent 764da6cbbb
commit db842d013d
19005 changed files with 197040 additions and 7 deletions

1
Task/Fork/0DESCRIPTION Normal file
View file

@ -0,0 +1 @@
In this task, the goal is to spawn a new [[process]] which can run simultaneously with, and independently of, the original parent process.

2
Task/Fork/1META.yaml Normal file
View file

@ -0,0 +1,2 @@
---
note: Programming environment operations

View file

@ -0,0 +1,11 @@
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
)

18
Task/Fork/Ada/fork.ada Normal file
View file

@ -0,0 +1,18 @@
with Ada.Text_IO,
POSIX.Process_Identification,
POSIX.Unsafe_Process_Primitives;
procedure Fork is
use Ada.Text_IO,
POSIX.Process_Identification,
POSIX.Unsafe_Process_Primitives;
begin
if Fork = Null_Process_ID then
Put_Line ("This is the new process.");
else
Put_Line ("This is the original process.");
end if;
exception
when others =>
Put_Line ("Something went wrong.");
end Fork;

View file

@ -0,0 +1,12 @@
var pid = fork()
switch (pid) {
case <0:
println ("fork error")
break
case 0:
println ("child")
break
default:
println ("parent")
break
}

View file

@ -0,0 +1,4 @@
MsgBox, 4, Fork, Start another process?
IfMsgBox, Yes
Run, %A_AhkPath% "%A_ScriptFullPath%"
MsgBox, 0, Fork, Stop this process.

22
Task/Fork/C++/fork.cpp Normal file
View file

@ -0,0 +1,22 @@
#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;
}

22
Task/Fork/C/fork-1.c Normal file
View file

@ -0,0 +1,22 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <err.h>
int main()
{
pid_t pid;
if (!(pid = fork())) {
usleep(10000);
printf("\tchild process: done\n");
} else if (pid < 0) {
err(1, "fork error");
} else {
printf("waiting for child %d...\n", (int)pid);
printf("child %d finished\n", (int)wait(0));
}
return 0;
}

3
Task/Fork/C/fork-2.c Normal file
View file

@ -0,0 +1,3 @@
waiting for child 3604...
child process: done
child 3604 finished

View file

@ -0,0 +1,2 @@
(require '[clojure.java.shell :as shell])
(shell/sh "echo" "foo") ; evaluates to {:exit 0, :out "foo\n", :err ""}

View file

@ -0,0 +1,7 @@
(let [search (future (shell/sh "find" "." "-name" "needle.*" :dir haystack))]
(while (and (other-stuff-to-do?) (not (future-done? search)))
(do-other-stuff))
(let [{:keys [exit out err]} @search]
(if (zero? exit)
(do-something-with out)
(report-errors-in err))))

View file

@ -0,0 +1,5 @@
(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."))))

View file

@ -0,0 +1,9 @@
-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").

View file

@ -0,0 +1,2 @@
c(fork).
fork:start().

View file

@ -0,0 +1,3 @@
USING: unix unix.process ;
[ "Hello form child" print flush 0 _exit ] [ drop "Hi from parent" print flush ] with-fork

View file

@ -0,0 +1,2 @@
fork \pid
print "pid = ";print pid;nl;

View file

@ -0,0 +1,87 @@
# (spawn child_fn next)
# Fork the child function as a process and return its pid, stdin, stdout, and
# stderr.
\spawn =
(
### Use error-checking versions of system routines
\pipe =
(\next
pipe \status\read\write
long_lt status 0 (die "pipe failed");
next read write
)
\dup2 =
(\oldfd\newfd\next
dup2 oldfd newfd \status
long_lt status 0 (die "dup2 failed");
next
)
\fdopen =
(\fd\mode\next
fdopen fd mode next;
die "fdopen failed"
)
\fork =
(\next
fork \pid
long_lt pid 0 (die "fork failed");
next pid
)
# Now here's the spawn function itself.
\child_fn\next
# First flush the parent's stdout and stderr to avoid any pending output
# accidentally getting pushed into the child's input. I've noticed this
# can happen when your script output is sent to a file or pipe instead of
# a console.
get_stdout \fh fflush fh \_
get_stderr \fh fflush fh \_
# Now create a series of pipes, each with a read and write side.
pipe \r_in\w_in
pipe \r_out\w_out
pipe \r_err\w_err
fork \pid
long_eq pid 0
(
# Child process.
# Duplicate one side of each pipe into stdin, stdout, and stderr
# as appropriate.
dup2 r_in 0;
dup2 w_out 1;
dup2 w_err 2;
# Close unused file handles. They're all unused because we duped the
# ones we need. Also, we must close w_in or the child hangs waiting
# for stdin to close.
close r_in; close w_in;
close r_out; close w_out;
close r_err; close w_err;
# Now run the child function, which can use stdin, stdout, and stderr
# normally.
child_fn
)
(
# Parent process. Open the opposite side of each pipe into three new
# file handles.
fdopen w_in "w" \child_in
fdopen r_out "r" \child_out
fdopen r_err "r" \child_err
# Close unused file handles. We don't close the ones we fdopened
# because they are still in play (i.e. fdopen does not dup).
close r_in;
close w_out;
close w_err;
# Return the child's pid, stdin, stdout, and stderr.
next pid child_in child_out child_err
)
)

View file

@ -0,0 +1,72 @@
\test_pipe =
(\next
print "== test_pipe";nl;
### Handy
# Echo entire contents of stream fh to stdout.
\file_print ==
(\fh\next
fgetc fh \ch
long_lt ch 0 next;
putchar ch;
file_print fh next
)
# Show a stream with a descriptive label.
\show_stream =
(\label\fh\next
print "[ ";print label;print ":";nl;
file_print fh;
print "]";nl;
next
)
### Here is a child function to try with spawn.
\child_fn =
(\next
print "Hello from child.";nl;
get_stdin \stdin
show_stream "input from parent" stdin;
print "Good bye from child.";nl;
die "Oops the child had an error!";
next
)
# Spawn the child.
spawn child_fn \pid\child_in\child_out\child_err
# Now we can communicate with the child through its three file handles.
print "Hello from parent, child pid = ";print pid;print ".";nl;
# Say something to the child.
(
# Override print routines for convenience.
\print = (fwrite child_in)
\nl = (print NL)
# Start talking.
print "Hello child, I am your parent!";nl;
print "OK, nice talking with you.";nl;
);
print "The parent is now done talking to the child.";nl;
# Now show the child's stdout and stderr streams.
show_stream "output from child" child_out;
show_stream "error from child" child_err;
# Wait for child to finish.
wait \pid\status
# LATER shift and logical bit operators
# LATER WEXITSTATUS and other wait macros
\status = (long_div status 256)
print "Child ";print pid;print " exited with status ";
print status;print ".";nl;
print "Good bye from parent.";nl;
print "test_pipe completed successfully.";nl;
next
)

View file

@ -0,0 +1 @@
test_pipe;

26
Task/Fork/Go/fork.go Normal file
View file

@ -0,0 +1,26 @@
package main
import (
"fmt"
"os"
)
func main() {
fmt.Printf("PID: %v\n", os.Getpid())
if len(os.Args) < 2 {
fmt.Println("Done.")
return
}
cp, err := os.StartProcess(os.Args[0], nil,
&os.ProcAttr{Files: []*os.File{nil, os.Stdout}},
)
if err != nil {
fmt.Println(err)
}
// Child process running independently at this point.
// We have its PID and can print it.
fmt.Printf("Child's PID: %v\n", cp.Pid)
if _, err = cp.Wait(); err != nil {
fmt.Println(err)
}
}

View file

@ -0,0 +1,17 @@
println "BEFORE PROCESS"
Process p = Runtime.runtime.exec('''
C:/cygwin/bin/sh -c "
/usr/bin/date +'BEFORE LOOP: %T';
for i in 1 2 3 4 ; do
/usr/bin/sleep 1;
/usr/bin/echo \$i;
done;
/usr/bin/date +'AFTER LOOP: %T'"
''')
p.consumeProcessOutput(System.out, System.err)
(0..<8).each {
Thread.sleep(500)
print '.'
}
p.waitFor()
println "AFTER PROCESS"

View file

@ -0,0 +1,5 @@
import System.Posix.Process
main = do
forkProcess (putStrLn "This is the new process")
putStrLn "This is the original process"

View file

@ -0,0 +1,11 @@
SYSTEM( RUN )
WRITE(Messagebox='?Y', IOStat=ios) "Another Fork?"
IF(ios == 2) ALARM(999) ! quit immediately
! assume this script is stored as 'Fork.hic'
SYSTEM(SHell='Fork.hic')
BEEP("c e g 'c")
WRITE(Messagebox="!") "Waiting ..."
ALARM(999) ! quit immediately

8
Task/Fork/Icon/fork.icon Normal file
View file

@ -0,0 +1,8 @@
procedure main()
if (fork()|runerr(500)) = 0 then
write("child")
else {
delay(1000)
write("parent")
}
end

10
Task/Fork/Lua/fork.lua Normal file
View file

@ -0,0 +1,10 @@
local posix = require 'posix'
local pid = posix.fork()
if pid == 0 then
print("child process")
elseif pid > 0 then
print("parent process")
else
error("unable to fork")
end

View file

@ -0,0 +1,5 @@
commandstring = First[$CommandLine] <> " -noprompt -run \"Put[Factorial[20],ToFileName[$TemporaryDirectory,ToString[temp1]]];Quit[]\""
->"MathKernel -noprompt -run \"Put[Factorial[20],ToFileName[$TemporaryDirectory,ToString[temp1]]];Quit[]\""
Run[commandstring]
->0

9
Task/Fork/PHP/fork.php Normal file
View file

@ -0,0 +1,9 @@
<?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";
?>

25
Task/Fork/Perl/fork-1.pl Normal file
View file

@ -0,0 +1,25 @@
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);
}

9
Task/Fork/Perl/fork-2.pl Normal file
View file

@ -0,0 +1,9 @@
use Proc::Fork;
run_fork {
child {
# child code ...
}
parent {
# parent code ...
}
};

8
Task/Fork/Perl/fork-3.pl Normal file
View file

@ -0,0 +1,8 @@
use Proc::Fork;
# parent code ...
run_fork {
child {
# child code ...
}
};
# parent code continues ...

15
Task/Fork/Perl/fork-4.pl Normal file
View file

@ -0,0 +1,15 @@
use Proc::Fork;
run_fork {
child {
# child code ...
}
parent {
# parent code ...
}
retry {
# retry code ...
}
error {
# error handling ...
}
};

View file

@ -0,0 +1,3 @@
(unless (fork) # In child process
(println *Pid) # Print the child's PID
(bye) ) # and terminate

7
Task/Fork/Python/fork.py Normal file
View file

@ -0,0 +1,7 @@
import os
pid = os.fork()
if pid > 0:
# parent code
else:
# child code

1
Task/Fork/REXX/fork.rexx Normal file
View file

@ -0,0 +1 @@
child = fork()

6
Task/Fork/Ruby/fork-1.rb Normal file
View file

@ -0,0 +1,6 @@
pid = fork
if pid
# parent code
else
# child code
end

4
Task/Fork/Ruby/fork-2.rb Normal file
View file

@ -0,0 +1,4 @@
fork do
# child code
end
# parent code

View file

@ -0,0 +1,10 @@
'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.

19
Task/Fork/Tcl/fork.tcl Normal file
View file

@ -0,0 +1,19 @@
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."
}
}
}