note 103307 deleted from function.pcntl-fork by danbrown
| From: | danbrown@php.net | Date: | Wed, 06 Apr 2011 15:29:47 +0000 |
| Subject: | note 103307 deleted from function.pcntl-fork by danbrown | ||
| References: | 1 | Groups: | php.notes |
| Request: | Send a blank email to php-notes+get-178565@lists.php.net to get a copy of this message | ||
Note Submitter: fgege
----
Answer for somebody 12-Aug-2010 10:46:
> - sometimes one process gets the result of the OTHER processes'
> query! (because both send their queries down the same socket,
> and it's pure luck who gets the reply)
This problem may be worked around with semaphores. Then you won't have concurrent reads/writes
on the socket. Assuming you'd like to write a child process that does nothing but keeping a
connection alive you could write the following code:
<?php
// this code is based on @somebody's example
$sem_key = mt_rand();
$conn = mysql_connect('server', 'username', 'password');
$f=pcntl_fork();
if ($f){
$sem = sem_get($sem_key);
// parent
while(true){
sleep(0.1);
if (!sem_acquire($sem)) die("parent: semaphore cannot be acquired");
$r=mysql_query("select $f;");
if(!$r) {posix_kill($f, SIGKILL);die($f.": ".mysql_error()."\n");}
list($x)=mysql_fetch_array($r);
if (!sem_release($sem)) die("parent: semaphore cannot be released");
echo ".";
if($x!=$f){posix_kill($f, SIGKILL);die ($f.": fail: $x!=$f\n ");}
}
}
else{
$sem = sem_get($sem_key);
// child
while(true){
sleep(0.5);
if (!sem_acquire($sem)) die("parent: semaphore cannot be acquired");
if (!mysql_ping($conn))
{
die("Lost connection");
}
if (!sem_release($sem)) die("parent: semaphore cannot be released");
echo "-";
}
}
?>
If you remove the sem_acquire/sem_release lines from the above code, then you'll really soon
meet the problem "somebody" mentioned.
Of course the sleep values in the above example are set especially to reproduce the "concurrent
read" problem if the semaphore is not there.
For a real keep-connection-alive example change the sleep values in the parent to 40, and in the
child to 15.