I don't think it's a bug. The fork() doesn't fail - the fork() is blocked. (Or rather, fork(1) fails, setting errno to EAGAIN).
You can easily test it. Copy the program, so you have foo calling itself and bar calling itself. Now do from on shell:
(ulimit -u 50 ./foo)
This will print a bunch of pids, and the program "hangs". Now from another shell do:
(ulimit -u 60 ./bar)
This will print 10 or less pids, and it hangs. Go back to the first window, kill the program, and issue a killall foo (or whatever is the equivalent on your system). Watch the output of the bars.
When reaching the maximum amount of processes set by ulimit, fork() blocks till another slot becomes available. | [reply] [d/l] [select] |
| [reply] |
I don't think it's on the system level, but it's perl that retries. I don't know exactly which functions Perl executes on backticks, but it's probably going to open some pipe. And here's a snippet from the function Perl_my_popen in util.c:
while ((pid = PerlProc_fork()) < 0) {
if (errno != EAGAIN) {
PerlLIO_close(p[This]);
PerlLIO_close(p[that]);
if (did_pipes) {
PerlLIO_close(pp[0]);
PerlLIO_close(pp[1]);
}
if (!doexec)
Perl_croak(aTHX_ "Can't fork");
return NULL;
}
sleep(5);
}
As you can see, if the fork fails with an EAGAIN, perl sleeps for 5 seconds and tries again.
A similar loop is found in Perl_my_popen_list in the same file. | [reply] [d/l] |
It would seem so. I run the script under strace and found that the qx op doesn't use fork syscall on my perl (Ubuntu Hardy), but clone syscall:
- A working qx...
21696 clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETT
+ID|SIGCHLD, child_tidptr=0x7f6015248770) = 21697
21697 close(5) = 0
21697 fcntl(6, F_SETFD, FD_CLOEXEC) = 0
21697 dup2(4, 1) = 1
21697 close(4) = 0
21697 close(3) = 0
21697 rt_sigaction(SIGFPE, {SIG_DFL}, {SIG_IGN}, 8) = 0
21697 execve("./my_program", ["./my_program"], [/* 11 vars */] <unfini
+shed ...>
- A non-working one...
21742 clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETT
+ID|SIGCHLD, child_tidptr=0x7f4143c25770) = -1 EAGAIN (Resource tempor
+arily unavailable)
21742 rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0
21742 rt_sigaction(SIGCHLD, NULL, {SIG_DFL}, 8) = 0
21742 rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
21742 nanosleep({5, 0}, <unfinished ...>
The problem is that the nanosleep syscall should not be happening.
| [reply] [d/l] [select] |
| [reply] |