*BSD で fork できない理由


#1

e$B$-$7$b$H$G$9e(B

http://redmine.ruby-lang.org/issues/show/270 e$B$K$b$"$ke(B
e$B!Ve(BFreeBSDe$B$de(BNetBSDe$B$O!$0lEYe(B pthread
e$B$r:n$k$H!$8e;OKv$r$7$Fe(B
e$B$be(B fork e$B8e!$e(Bpthread
e$B$r:n$m$&$H$9$k$H;I$5$k!W$K4X$9$k7o$J$N$G$9$,!"e(B
e$B8D?ME*$K;H$C$F$$$k%D!<%k$,$3$l$N$?$a$Ke(B Ruby1.9
e$B$K0\9T$G$-$J$$$G$$$^$9!#e(B

e$B$3$l$Oe(B OS e$BB&$N%P%0$J$s$G$7$g$&$+!"$=$l$H$be(B POSIX
e$BE*$K$7$g$&$,$J$$e(B
e$B;EMM$J$s$G$7$g$&$+!#e(B
FreeBSD e$B$Ne(B send-pr e$B$re(B thread
e$B$G8!:w$7$F$_$?46$8$G$O!Js9p$5$l$Fe(B
e$B$J$5$=$&$J$N$G!%P%0$H$$$&$3$H$J$iJs9p$7$?$$$N$G$9$,!#e(B


#2

At Tue, 31 Mar 2009 18:48:46 +0900,
KISHIMOTO, Makoto wrote:

http://redmine.ruby-lang.org/issues/show/270
FreeBSDNetBSD pthread
fork pthread
Ruby1.9

OS POSIX

FreeBSD send-pr thread


POSIX/Pthread

http://www.freebsd.org/cgi/query-pr.cgi?pr=threads/101323

JDK/CPython


fork+signal spawn+IPC
daemon daemontools (Mac) launchd
()


#3

In message removed_email_address@domain.invalid
on Tue, 31 Mar 2009 18:48:46 +0900,
KISHIMOTO, Makoto removed_email_address@domain.invalid wrote:

http://redmine.ruby-lang.org/issues/show/270 e$B$K$b$"$ke(B
e$B!Ve(BFreeBSDe$B$de(BNetBSDe$B$O!$0lEYe(B pthread e$B$r:n$k$H!$8e;OKv$r$7$Fe(B
e$B$be(B fork e$B8e!$e(Bpthread e$B$r:n$m$&$H$9$k$H;I$5$k!W$K4X$9$k7o$J$N$G$9$,!e(B

e$B$3$l$Oe(B OS e$BB&$N%P%0$J$s$G$7$g$&$+!$=$l$H$be(B POSIX e$BE*$K$7$g$&$,$J$$e(B
e$B;EMM$J$s$G$7$g$&$+!#e(B
FreeBSD e$B$Ne(B send-pr e$B$re(B thread e$B$G8!:w$7$F$_$?46$8$G$O!Js9p$5$l$Fe(B
e$B$J$5$=$&$J$N$G!%P%0$H$$$&$3$H$J$iJs9p$7$?$$$N$G$9$,!#e(B
e$B40A4$KM}2r$7$F$$$k$o$1$G$O$"$j$^$;$s$,!"e(BNetBSDe$B$Ne(Bpthread_atfork(3)e$B$K!"e(B

CAVEATS
After calling fork(2) from a multithreaded process, it is only safe
to
call async-signal-safe functions until calling one of the exec(3)
func-
tions. The pthread_*() functions are not async-signal-safe, so it
is not
safe to use such functions in the child handler.

e$B$J$s$F=q$+$l$F$$$k$"$?$j$b4X78$"$j$=$&$K;W$($^$9!#e(B


#4

In article removed_email_address@domain.invalid,
Urabe S. removed_email_address@domain.invalid writes:

e$B$A$g$C$H$3$N!Ve(BPthreade$B$N;EMME*$K$bF0:nJ]>c30!W$C$FItJ,$N:,5r$,$I$&$,$s$P$C$F$b<+e(B
e$BNO$GH/8+$G$-$J$$$N$G!"$h$m$7$1$l$P2?$+%]%$%s%?$r<($7$F$$$?$@$1$^$;$s$+e(B?

fork e$B$N9`$K$"$ke(B

Consequently, to avoid errors, the child process may only
execute async-signal-safe operations until such time as
one of the exec functions is called.

http://www.opengroup.org/onlinepubs/009695399/functions/fork.html

e$B$H$$$&$H$3$m$J$s$8$c$J$$$+$H;W$$$^$9!#e(B

async-signal-safe function e$B$N%j%9%H$Oe(B
http://www.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_04.html
e$B$K:$C$F$$$F!"e(Bpthread_create e$B$OF~$C$F$$$^$;$s!#e(B

e$B$J$N$G!"5,3J$H$7$F$O!"e(Bfork e$B$G$G$-$?;R%W%m%;%9$G$Oe(B exec
e$B$9$ke(B
e$B$^$Ge(B pthread_create e$B$r;H$C$F$O$$$1$^$;$s!#e(B


#5

e$BKNIt$G$9!#e(B

Akinori MUSHA e$B$5$s$O=q$-$^$7$?e(B:

e$B$3$l$Oe(B OS e$BB&$N%P%0$J$s$G$7$g$&$+!"$=$l$H$be(B POSIX e$BE*$K$7$g$&$,$J$$e(B
e$B;EMM$J$s$G$7$g$&$+!#e(B
FreeBSD e$B$Ne(B send-pr e$B$re(B thread e$B$G8!:w$7$F$_$?46$8$G$O!Js9p$5$l$Fe(B
e$B$J$5$=$&$J$N$G!%P%0$H$$$&$3$H$J$iJs9p$7$?$$$N$G$9$,!#e(B

e$B!!Js9p$5$lG<1$b$5$l$F$$$^$9$,!";DG0$J$,$i:#$N$H$3$m=$@5M=Dj$Oe(B
e$B$"$j$^$;$s!#e(BPOSIX/Pthread e$B$N;EMME*$K$bF0:nJ]>Z30$J$N$G!"I,;`$Ke(B
e$B4hD%$C$F$^$G2?$H$+$7$h$&$H$$$&F0$-$K$O$J$C$F$$$J$$$h$&$G$9!#e(B

e$B$A$g$C$H$3$N!Ve(BPthreade$B$N;EMME*$K$bF0:nJ]>c30!W$C$FItJ,$N:,5r$,$I$&$,$s$P$C$F$b<+e(B
e$BNO$GH/8+$G$-$J$$$N$G!"$h$m$7$1$l$P2?$+%]%$%s%?$r<($7$F$$$?$@$1$^$;$s$+e(B?
pthread_atfork()e$B$H$+$$$&4X?t$,$"$k$h$&$Ge(B
http://www.opengroup.org/onlinepubs/009695399/functions/pthread_atfork.html
e$B$5$9$,$KF0:nJ]>c30$C$F$3$H$O$J$$$s$8$c$J$$$+$H;W$&$s$G$9$1$I$b!#e(B


#6

e$B$-$7$b$H$G$9e(B

e$B3MM$"$j$,$H$&$4$6$$$^$9!#e(Bspawne$B$G$d$C$F$_$^$9!#e(B

e$B;R%W%m%;%9$G!I8=F~NO$r?F$+$i0z$-7Q$$$@%Q%$%W$K$D$J$.$+$($F$+$ie(Bexece$B$7$F$ke(B e$B!J=PNO$rJL%W%m%0%i%$N%U%#%k%?$KDL$7$F$k!K$N$G!%7%%k$N%U%!%$%k%G%#%9%/%j%W%?$re(B
e$B;XDj$7$?%j%@%$%l%/%H$r;H$C$F$G$-$J$$$+$d$C$F$_$^$9!#B?J,$G$-$=$&!#e(B

forke$B$r;H$C$F$k$H;W$$9~$s$G$?=j$G$O;H$C$F$$$J$/$F!"e(B

e$BA4$/K:$l$F$?ItJ,$G;H$C$F$$$?e(Borz

PS. Ruby
spawne$B$G8!:w$7$?$i!":#7ne(B15e$BF|$N%;%%J!<$r$$D$1$^$7$?!#e(B
http://www.fsij.org/homepage/wiki/MonthlyMeeting2009Apr


#7

Urabe S. e$B$5$s$O=q$-$^$7$?e(B:

one of the exec functions is called.
e$B$^$Ge(B pthread_create e$B$r;H$C$F$O$$$1$^$;$s!#e(B

e$B$J$k$[$I!#$"$j$,$H$&$4$6$$$^$9!#e(B

e$B$7$+$7$9$k$He(Bpthread_atforke$B$Ne(BRATIONALEe$B$K$"$k!Ve(Bforke$B$NA0$Ke(Bmutexe$B$r3NJ]$7$Fe(Bforke$B8e$Ke(B
e$B3+J|$9$k!W$C$F$d$D$O$=$b$=$bL5M}$J$s$G$9$M$(!#e(Bpthread_mutex_unlocke$B$be(Basync-
signal-safee$B$G$O$J$$$h$&$G$9$7!#e(B


#8

Tanaka A. e$B$5$s$O=q$-$^$7$?e(B:

one of the exec functions is called.
e$B$^$Ge(B pthread_create e$B$r;H$C$F$O$$$1$^$;$s!#e(B
e$B$J$k$[$I!#$"$j$,$H$&$4$6$$$^$9!#e(B


#9

In article removed_email_address@domain.invalid,
KISHIMOTO, Makoto removed_email_address@domain.invalid writes:

e$B;R%W%m%;%9$G!I8=F~NO$r?F$+$i0z$-7Q$$$@%Q%$%W$K$D$J$.$+$($F$+$ie(Bexece$B$7$F$ke(B e$B!J=PNO$rJL%W%m%0%i%$N%U%#%k%?$KDL$7$F$k!K$N$G!%7%%k$N%U%!%$%k%G%#%9%/%j%W%?$re(B
e$B;XDj$7$?%j%@%$%l%/%H$r;H$C$F$G$-$J$$$+$d$C$F$_$^$9!#B?J,$G$-$=$&!#e(B

forke$B$r;H$C$F$k$H;W$$9~$s$G$?=j$G$O;H$C$F$$$J$/$F!"e(B

e$BA4$/K:$l$F$?ItJ,$G;H$C$F$$$?e(Borz

e$B$$=$i$/%7%%k$OITMW$@$H;W$$$^$9$h!#e(B
(e$B%7%%k<+BN$rF0$+$9$N$,L\E
$G$J$$8B$j$Oe(B)

spawn e$B$N%^%K%e%"%ke(B (rdoc) e$B$rFI$s$G$_$F$/$@$5$$!#e(B

e$B$J$*!e(B1.9.2 e$B$Ne(B open3
e$B$K$O!%Q%$%W%i%$%s$J$I$"$j$,$A$J5/F0$Ne(B
e$B$7$+$?$O4JC1$K9T$($k%a%=%C%I$rIU$1$F$"$k$N$G!"Lr$KN)$D$+$b$7e(B
e$B$l$^$;$s!#e(B

PS. Ruby spawne$B$G8!:w$7$?$i!":#7ne(B15e$BF|$N%;%%J!<$r$$D$1$^$7$?!#e(B
http://www.fsij.org/homepage/wiki/MonthlyMeeting2009Apr

e$BOC<T$O;d$G$9!#6=L#$,$"$k$+$?$O$I$&$>!#e(B


#10

In article removed_email_address@domain.invalid,
KISHIMOTO, Makoto removed_email_address@domain.invalid writes:

Pythone$B$Ne(Bsubprocesse$B$_$?$$$J5!G=$,DI2C$5$l$F$?$s$G$9$M!#e(B

e$B$O$$!"e(BPython e$B$Ne(B subprocess e$B$O;29M$K$7$^$7$?!#e(B

e$B7k2L$H$7$F$G$-$?e(B API
e$B$,;w$F$$$k$+$I$&$+$O2x$7$$$H$3$m$G$9$,!"e(B
e$B$I$A$i$b%f!<%6$NL\E*$rD>@\E*$K;Y1g$9$k$h$&$K0U?^$7$F$$$k$H;We(B
e$B$$$^$9!#e(B


#11

spawn e$B$N%^%K%e%"%ke(B (rdoc) e$B$rFI$s$G$_$F$/$@$5$$!#e(B

e$B$"$j$,$H$&$4$6$$$^$9!#%j%U%!%l%s%9%^%K%e%"%k$7$+FI$s$G$^$;$s$G$7$?!#e(B
Pythone$B$Ne(Bsubprocesse$B$_$?$$$J5!G=$,DI2C$5$l$F$?$s$G$9$M!#e(B

e$B$J$<$+%7%%k7PM3$G$O$&$^$/$$$+$J$+$C$?$s$G$9$,!"e(Bspawne$B$N%*%W%7%g%s0z?t$re(B
e$B;H$C$F$&$^$/$$$-$^$7$?!#e(B

e$B$J$*!e(B1.9.2 e$B$Ne(B open3 e$B$K$O!%Q%$%W%i%$%s$J$I$"$j$,$A$J5/F0$Ne(B
e$B$7$+$?$O4JC1$K9T$($k%a%=%C%I$rIU$1$F$"$k$N$G!"Lr$KN)$D$+$b$7e(B
e$B$l$^$;$s!#e(B

waitpide$B$GBT$D$h$&$K$7$?$+$C$?$N$G!e(Bpide$B$,<h$l$J$$e(Bpopene$B7O$O;H$($J$$$He(B
e$BH=CG$7$?<BAu;~$N5-21$,$$k$N$G$9$,!"$3$A$i$b:#$Oe(Bpide$B$,<h$l$k$h$&$K$J$C$Fe(B
e$B$$$k$N$G$9$M!#e(Bopen3e$B$r;H$&$[$&$b<B83$7$F$_$^$9!#e(B


#12

waitpide$B$GBT$D$h$&$K$7$?$+$C$?$N$G!e(Bpide$B$,<h$l$J$$e(Bpopene$B7O$O;H$($J$$$He(B
e$BH=CG$7$?<BAu;~$N5-21$,$$k$N$G$9$,!"$3$A$i$b:#$Oe(Bpide$B$,<h$l$k$h$&$K$J$C$Fe(B
e$B$$$k$N$G$9$M!#e(Bopen3e$B$r;H$&$[$&$b<B83$7$F$_$^$9!#e(B

Open3.pipeline_w e$B$,$&$^$/;H$($^$7$?!#e(B
waitpid e$B$Oe(B wait_thread e$B$K$b$C$F$+$l$F$7$^$&$N$G!"85$Oe(B
waitpid
e$B$@$C$?$H$3$m$Oe(B wait_thread.value e$B$GBT$D$h$&$K$7$^$7$?!#e(B