473,324 Members | 2,196 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,324 software developers and data experts.

php fork/wait, strange behaviour

Hi

i have to develop a multihreaded php application on linux, then through
pcntl_fork and wait.
I tried it, but there something going wrong, i think.
The difference whit other languages like c and python is that the wait
cannot handle correctly all signals from dead children in two cases:

1 - two or more children dies (about) at the same time time
2 - the chidren dies before pcntl_wait start

in fact the wait does not return the chld's pid, but "-1"
that is he knows that a child is dead, but he cannot say the correct
pid.

I made two scripts (below), one php and one python that should do the same
thing. The python one run correctly , the php no.
You can verify their behaviour, if you want.
You can comment, o indecrease or increase the sleep call in the php script
to note what happend at the wait call
At the end i ask you, am i doing someting wrong?
Is the php fork/wait behaviour bugged?

thanks in advance

Andrea
#!/usr/bin/php
<?php
$children = array();

function child($id)
{
$p=posix_getpid();
echo "child: ($id) pid ($p)\n";
sleep(rand(1,5));
echo "child:end pid ($p)\n";

exit(0);
}
$i=0;
while($i<10)
{
$pid = pcntl_fork();

if($pid == -1)
die("Could not fork!");
elseif($pid == 0)
child($i);
else
{
$children[] = $pid;
$i++;
}
}

print "dad:sleep a bit...\n";
$i=10;
while($i)
{
$pid_dead = pcntl_waitpid(-1,$status);
if ($pid_dead != 0)
{
echo "dad:dead child pid ($pid_dead)\n";
if(array_search($pid_dead,$children))
{
unset($children[$pid_dead]);
print "dad:unset pid ($pid_dead)\n ";
$i--;
}
else
{
$i--;
print "dad:pid ($pid_dead) not tracked\n";
}
}
}

echo "dad: all dead\n"
?>
#!/usr/bin/python

import sys
import os
import time

def child(i):
print "child: (%d) pid (%d)" % (i,os.getpid())
sys.exit(0);
children=[]
i=0
while i<10:
i+=1
pid = os.fork()
if not pid:
child(i)
else:
children.append(pid)

print "dad:sleep a lot..."
time.sleep(2)
while len(children):
pid_dead = os.waitpid(-1,os.WNOHANG)

if pid_dead[0] != 0:
print "dad:dead pid (%d)" % pid_dead[0]
try:
children.index(pid_dead[0])
children.remove(pid_dead[0])
print "dad:eliminato pid (%d) " % pid_dead[0]
except:
print "dad:pid (%d) not in children" %
pid_dead[0]
time.sleep(0.5)
print "dad: all dead"

Feb 7 '08 #1
3 2958
RedWiz wrote:
Hi

i have to develop a multihreaded php application on linux, then through
pcntl_fork and wait.
I tried it, but there something going wrong, i think.
The difference whit other languages like c and python is that the wait
cannot handle correctly all signals from dead children in two cases:

1 - two or more children dies (about) at the same time time
2 - the chidren dies before pcntl_wait start

in fact the wait does not return the chld's pid, but "-1"
that is he knows that a child is dead, but he cannot say the correct
pid.
In your case, it's an array problem. You are handling the $children array
the wrong way.
{
$children[] = $pid;
$i++;
}
Thsi will create an array like (0=>1234, 1=>1235, 2=>1236).
if(array_search($pid_dead,$children))
{
unset($children[$pid_dead]);
print "dad:unset pid ($pid_dead)\n ";
$i--;
}
What happens here if $pid_dead is 1234? You'll never unset the element 0 of
the array.
You have two options:
- RTFM on array_search, and check for a boolean false return value (hint:
use the === operator)
- Instead of storing the PIDs in the array as the contents, store the PIDs
as the keys, like this:
$children[$pid] = true;
And try using ( isset($children[$pid]) ) as the condition for the "if"
statement.
AFAIK, there is nothing wrong with the pcntl functions. If several children
die very close to each other, they'll be left as zombies until the parent
waits for every one of them.
Cheers,
--
----------------------------------
Iván Sánchez Ortega -ivansanchez-algarroba-escomposlinux-punto-org-

Proudly running Debian Linux with 2.6.24-1-amd64 kernel, KDE 3.5.8, and PHP
5.2.5-2 generating this signature.
Uptime: 18:35:54 up 8 days, 5:20, 4 users, load average: 0.87, 0.80, 0.66

Feb 7 '08 #2
>
Thsi will create an array like (0=>1234, 1=>1235, 2=>1236).
yes
>if(array_search($pid_dead,$children))
{
unset($children[$pid_dead]);
print "dad:unset pid ($pid_dead)\n ";
$i--;
}

What happens here if $pid_dead is 1234? You'll never unset the element 0 of
the array.
you're right, that is an error, but it doesn't interfere with the wait
call.
Cause in every way, wait return some "-1"s
AFAIK, there is nothing wrong with the pcntl functions. If several
children die very close to each other, they'll be left as zombies until
the parent waits for every one of them.
going to find some example.

ty

Feb 7 '08 #3
RedWiz wrote:
Cause in every way, wait return some "-1"s
Using your example, wait never returned -1 in my computer.

--
----------------------------------
Iván Sánchez Ortega -ivansanchez-algarroba-escomposlinux-punto-org-

MSN:i_*************************@hotmail.com
Jabber:iv*********@jabber.org ; iv*********@kdetalk.net
Feb 7 '08 #4

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
by: Benoit Dejean | last post by:
hello, i have a question about forking processes atm, i have some code which i want to rewrite os.system("cd ~ && exec " + cmd + " & disown") i want to remove this os.system call
6
by: shellcode | last post by:
the code: ------fork.c------ #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/wait.h> #include <unistd.h> int main() {
1
by: Huey | last post by:
Hi All, I encountered a funny thing, and my code schetch as below: #define READ 0 #define WRITE 1 int byteRead, status, pd; char buff;
1
by: Alexander N. Spitzer | last post by:
I am trying to write a program that will fork a process, and execute the given task... the catch is that if it runs too long, I want to clean it up. this seemed pretty straight forward with a...
16
by: mishra | last post by:
Hi, i thied the following code.. # include<stdio.h> int main() { int a; printf("Hello..."); a=fork(); printf("hi\n"); return(0);
27
by: steve | last post by:
I was given the following code, and asked what the possible outputs could be. We're learning about processes and forking. int value; int main(){ int pid, number = 1; value = 2; pid = fork();...
1
by: vduber6er | last post by:
Hi I want to have a wait page while the rest of the cgi does its process, but it seems like the wait page waits till everything is complete and never appears. I've tried forking twice already as...
3
by: manjuscripts | last post by:
The output of the below program is "hihi" as "hi" is printed by both parent and child process #include<stdio.h> main() { printf("hi"); fork(); }
4
by: fussbol12 | last post by:
I cannot find what is giving me the segfault in my code...I used printf statements to check for errors....anyone see the problem?? #include <stdio.h> #include <sys/ptrace.h> #include...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
1
by: Shćllîpôpď 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
by: af34tf | last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.