PHP: pcntl_fork - Manual

downloads | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | conferences | my php.net

search for in the

pcntl_getpriority pcntl_exec

Last updated: Sat, 27 Jan 2007

view this page in

# pcntl_fork

(PHP 4 >= 4.1.0, PHP 5)

pcntl_fork -- Forks the currently running process

## Description

int pcntl_fork ( void )

The pcntl_fork() function creates a child process that differs from the parent process only in its PID and PPID. Please see your system's fork(2) man page for specific details as to how fork works on your system.

On success, the PID of the child process is returned in the parent's thread of execution, and a 0 is returned in the child's thread of execution. On failure, a -1 will be returned in the parent's context, no child process will be created, and a PHP error is raised.

Пример 1. pcntl_fork() example

`<?php
$pid = pcntl_fork();
if ($pid == -1) {
die('could not fork');
} else if ($pid) {
// we are the parent
pcntl_wait($status); //Protect against Zombie children
} else {
// we are the child
}
?>`

See also pcntl_waitpid() and pcntl_signal().

add a note User Contributed Notes
pcntl_fork
amatsak at chestnutsoftware dot com
25-Oct-2006 02:06
`The reason for the MySQL "Lost Connection during query" issue when forking is the fact that the child process inherits the parent's database connection. When the child exits, the connection is closed. If the parent is performing a query at this very moment, it is doing it on an already closed connection, hence the error.
An easy way to avoid this is to create a new database connection in parent immediately after forking. Don't forget to force a new connection by passing true in the 4th argument of mysql_connect():
<?
// Create the MySQL connection
$db = mysql_connect($server, $username, $password);
$pid = pcntl_fork();
if ( $pid == -1 ) {
// Fork failed
exit(1);
} else if ( $pid ) {
// We are the parent
// Can no longer use $db because it will be closed by the child
// Instead, make a new MySQL connection for ourselves to work with
$db = mysql_connect($server, $username, $password, true);
} else {
// We are the child
// Do something with the inherited connection here
// It will get closed upon exit
exit(0);
?>
This way, the child will inherit the old connection, will work on it and will close upon exit. The parent won't care, because it will open a new connection for itself immediately after forking.
Hope this helps.`
xuecan at google dot com
26-Aug-2006 09:59
`I think this simple code can help understand how fork works:
<?
echo "posix_getpid()=".posix_getpid().", posix_getppid()=".posix_getppid()."\n";
$pid = pcntl_fork();
if ($pid == -1) die("could not fork");
if ($pid) {
echo "pid=".$pid.", posix_getpid()=".posix_getpid().", posix_getppid()=".posix_getppid()."\n";
} else {
echo "pid=".$pid.", posix_getpid()=".posix_getpid().", posix_getppid()=".posix_getppid()."\n";
}
?>`
Jeff
21-Jul-2006 02:45
`In response to Jon Dowland, a fork is actually not that expensive of an operation. Yes, a fork creates a copy of the process, so you would think it would be an expensive operation, but instead operating systems implement what is known as "copy-on-write." Instead of actually making a copy of the data, both processes reference the same data as long as they're only reading from it. Once a process goes to write to the data, then the child process gets its own copy of it. So, the majority of the PHP engine would not have to be copied and thus this would not be very expensive.`
spam at kacke dot de
03-Mar-2006 10:52
`I disagree too with reinoud at hyves dot nl too.
It seems youll always get the mysql-error 0 "lost connetion during query" when massive forking at the same time like
while x = mysql_fetch_array() -> fork
If you put for example a usleep between each fork youll dont loose the connection.
I figured that out sometimes and maybe its a "workaround" that helps
Toppi`
rob at bronco dot co dot uk
26-May-2005 07:53
`I disagree with reinoud at hyves dot nl. I have multiple examples of software which connects to a database then forks a great number of times, and every child has full access to the database link resource. The only issues with forking and MySQL that I have experienced is that you may get the occasional "MySQL server has gone away", although that particular error is probably more related to massively overloading a database.`
arnold at helderhosting dot nl
13-Feb-2005 07:12
`It is not possible to use the function 'pcntl_fork' when PHP is used as Apache module. You can only use pcntl_fork in CGI mode or from command-line.
Using this function will result in: 'Fatal error: Call to undefined function: pcntl_fork()'`
ej <at> wellkeeper dot com
30-Jun-2004 10:56
`If you understand what a UNiX fork() command actually does, then the behaviour astrolox describes below is precisely what one would expect. A fork() command creates an identical process (save for the PID) and that includes the TEXT segment, DATA segment, stack, heap, file descriptors, etc. If you don't want the child to have what's in the buffer, just throw it out (in the child - the parent doesn't need to do anything differently).
As for his new server that doesn't display the same behaviour, I'm not sure what to say. It would be a mistake for PHP to throw away that buffer for you behind the scenes because someone may well want a child that has access to that buffer. If fork() is properly implemented the *ONLY* thing that is different in the child is that it has it's own PID.`
astrolox at lawyersonline dot co dot uk
31-Mar-2004 03:40
`When using php 4.3.3, I found that output buffering can really confuse you if you use fork within your script.
The buffer (everything which hasn't been placed on the screen yet) is copied to the child process.
This means that when the child flushes it's buffer, which happens automatically when the script ends, you will get a copy of everything which your code (before the fork) tried to place on to the screen.
This causes it to look like all your code before the fork has run twice, when actually it hasn't.
This doesn't happen on my other server running a newer version of php, but that might be a configuration issue.
Note that using ob_implicit_flush() at the start of the script doesn't appear to solve the problem. Adding ob_end_flush() before the pcntl_fork() command does solve the problem.
Example:
<?
echo "This is an echo before I called the fork command\n";
// uncomment the next line to fix the described problem
#ob_end_flush();
$pid = pcntl_fork();
if ($pid == -1) {
die("could not fork");
} else if ($pid) {
echo "I am the parent, pid = ". $pid ."\n";
} else {
echo "I am the child, pid = ". $pid ."\n";
}
?>
Output, before "fixed":
This is an echo before I called the fork command
I am the parent, pid = 15449
This is an echo before I called the fork command
I am the child, pid = 0
Output, after "fixed":
This is an echo before I called the fork command
I am the parent, pid = 15023
I am the child, pid = 0`
ben at gelbnet dot com
25-Sep-2002 03:54
`I was writing a shell script to get input from a user, however, I needed my script to time out after a certain number of seconds if the user didn't enter enough data. The code below descibes the method I used. It's a little hairy but it does work.
-Ben
#!/home/ben/php/bin/php -q
<?
//GLOBALS
$RETURN_CHAR = "\n";
$TIMEOUT = 5; //number of seconds to timeout on input
$PID = getmypid();
$CHILD_PID = 0;
//Make sure program execution doesn't time out
set_time_limit(0);
function set_timeout() {
global $PID;
global $CHILD_PID;
global $TIMEOUT;
$CHILD_PID = pcntl_fork();
if($CHILD_PID == 0) {
sleep($TIMEOUT);
posix_kill($PID, SIGTERM);
exit;
}
}
function clear_timeout() {
global $CHILD_PID;
posix_kill($CHILD_PID, SIGTERM);
}
// read_data()
// gets a line of data from STDIN and returns it
function read_data() {
$in = fopen("php://stdin", "r");
set_timeout();
$in_string = fgets($in, 255);
clear_timeout();
fclose($in);
return $in_string;
}
// write_data($outstring)
// writes data to STDOUT
function write_data($outstring) {
$out = fopen("php://stdout", "w");
fwrite($out, $outstring);
fclose($out);
}
while(1) {
write_data("say something->");
$input = read_data();
write_data($RETURN_CHAR.$input);
}
?>`
add a note
pcntl_getpriority pcntl_exec

Last updated: Sat, 27 Jan 2007
show source | credits | stats | sitemap | contact | advertising | mirror sites
Copyright © 2001-2007 The PHP Group
All rights reserved.
This mirror generously provided by: Yahoo! Inc.
Last updated: Sat Mar 10 10:36:09 2007 PST