PHP: Process Control Functions - Manual
PHP  
downloads | documentation | faq | getting help | mailing lists | | php.net sites | links 
search for in the  
previouspg_updatepcntl_execnext
Last updated: Fri, 30 Aug 2002
view the printer friendly version or the printer friendly version with notes or change language to English | Brazilian Portuguese | Chinese | Czech | Dutch | Finnish | French | German | Italian | Japanese | Korean | Polish | Romanian | Russian | Spanish | Swedish | Turkish

LXXXI. Process Control Functions

Bevezet�s

Process Control support in PHP implements the Unix style of process creation, program execution, signal handling and process termination. Process Control should not be enabled within a webserver environment and unexpected results may happen if any Process Control functions are used within a webserver environment.

This documentation is intended to explain the general usage of each of the Process Control functions. For detailed information about Unix process control you are encouraged to consult your systems documentation including fork(2), waitpid(2) and signal(2) or a comprehensive reference such as Advanced Programming in the UNIX Environment by W. Richard Stevens (Addison-Wesley).

K�vetelm�nyek

Az itt le�rt f�ggv�nyek a standard modulban tal�lhat�ak, ami mindig rendelkez�sre �ll.

Telep�t�s

Process Control support in PHP is not enabled by default. You will need to use the --enable-pcntl configuration option when compiling PHP to enable Process Control support.

Megjegyz�s: Currently, this module will not function on non-Unix platforms (Windows).

Fut�sidej� be�ll�t�sok

Ez a kiterjeszt�s semmilyen konfigur�ci�s be�ll�t�sokat nem defini�l.

Er�forr�s t�pusok

Ez a kiterjeszt�s semmilyen er�forr�s t�pust nem defini�l.

El�re defini�lt �lland�k

The following list of signals are supported by the Process Control functions. Please see your systems signal(7) man page for details of the default behavior of these signals.

WNOHANG (integer)

WUNTRACED (integer)

SIG_IGN (integer)

SIG_DFL (integer)

SIG_ERR (integer)

SIGHUP (integer)

SIGINT (integer)

SIGQUIT (integer)

SIGILL (integer)

SIGTRAP (integer)

SIGABRT (integer)

SIGIOT (integer)

SIGBUS (integer)

SIGFPE (integer)

SIGKILL (integer)

SIGUSR1 (integer)

SIGSEGV (integer)

SIGUSR2 (integer)

SIGPIPE (integer)

SIGALRM (integer)

SIGTERM (integer)

SIGSTKFLT (integer)

SIGCLD (integer)

SIGCHLD (integer)

SIGCONT (integer)

SIGSTOP (integer)

SIGTSTP (integer)

SIGTTIN (integer)

SIGTTOU (integer)

SIGURG (integer)

SIGXCPU (integer)

SIGXFSZ (integer)

SIGVTALRM (integer)

SIGPROF (integer)

SIGWINCH (integer)

SIGPOLL (integer)

SIGIO (integer)

SIGPWR (integer)

SIGSYS (integer)

SIGBABY (integer)

P�ld�k

This example forks off a daemon process with a signal handler.

P�lda 1. Process Control Example

<?php

$pid = pcntl_fork();
if ($pid == -1) {
     die("could not fork"); 
} else if ($pid) {
     exit(); // we are the parent 
} else {
     // we are the child
}

// detatch from the controlling terminal
if (!posix_setsid()) {
    die("could not detach from terminal");
}

// setup signal handlers
pcntl_signal(SIGTERM, "sig_handler");
pcntl_signal(SIGHUP, "sig_handler");

// loop forever performing tasks
while(1) {

    // do something interesting here

}

function sig_handler($signo) {

     switch($signo) {
         case SIGTERM:
             // handle shutdown tasks
             exit;
             break;
         case SIGHUP:
             // handle restart tasks
             break;
         default:
             // handle all other signals
     }

}

?>

L�sd m�g

A look at the section about POSIX functions may be useful.

Tartalom
pcntl_exec --  Executes specified program in current process space
pcntl_fork -- Forks the currently running process
pcntl_signal -- Installs a signal handler
pcntl_waitpid -- Waits on or returns the status of a forked child
pcntl_wexitstatus --  Returns the return code of a terminated child
pcntl_wifexited --  Returns TRUE if status code represents a successful exit
pcntl_wifsignaled --  Returns TRUE if status code represents a termination due to a signal
pcntl_wifstopped --  Returns TRUE if child process is currently stopped
pcntl_wstopsig --  Returns the signal which caused the child to stop
pcntl_wtermsig --  Returns the signal which caused the child to terminate
User Contributed Notes
Process Control Functions
add a note about notes
[email protected]
22-Feb-2002 10:59

If you use Zend Optimizer 1.20, it is not compatible with PCNTL. You'll get an error message stating: '[Zend Optimizer] Zend Optimizer 1.2.0 is incompatible with pcntl 1.0 in Unknown on line 0'.

You get this error message when you compile using the --enable-pcntl option.

daniel[at]lorch.cc
27-Feb-2002 10:48

This piece of code helped me to find out what signals are being sent to my process:

function sig_identify($signo) {
switch($signo) {
case SIGFPE: return 'SIGFPE';
case SIGSTOP: return 'SIGSTOP';
case SIGHUP: return 'SIGHUP';
case SIGINT: return 'SIGINT';
case SIGQUIT: return 'SIGQUIT';
case SIGILL: return 'SIGILL';
case SIGTRAP: return 'SIGTRAP';
case SIGABRT: return 'SIGABRT';
case SIGIOT: return 'SIGIOT';
case SIGBUS: return 'SIGBUS';
case SIGPOLL: return 'SIGPOLL';
case SIGSYS: return 'SIGSYS';
case SIGCONT: return 'SIGCONT';
case SIGUSR1: return 'SIGUSR1';
case SIGUSR2: return 'SIGUSR2';
case SIGSEGV: return 'SIGSEGV';
case SIGPIPE: return 'SIGPIPE';
case SIGALRM: return 'SIGALRM';
case SIGTERM: return 'SIGTERM';
case SIGSTKFLT: return 'SIGSTKFLT';
case SIGCHLD: return 'SIGCHLD';
case SIGCLD: return 'SIGCLD';
case SIGIO: return 'SIGIO';
case SIGKILL: return 'SIGKILL';
case SIGTSTP: return 'SIGTSTP';
case SIGTTIN: return 'SIGTTIN';
case SIGTTOU: return 'SIGTTOU';
case SIGURG: return 'SIGURG';
case SIGXCPU: return 'SIGXCPU';
case SIGXFSZ: return 'SIGXFSZ';
case SIGVTALRM: return 'SIGVTALRM';
case SIGPROF: return 'SIGPROF';
case SIGWINCH: return 'SIGWINCH';
case SIGPWR: return 'SIGPWR';
}
}

function sig_handler($signo) {
echo "Caught " . sig_identify($signo) . " (" . $signo . ") on " . posix_getpid() . "\n";
}

pcntl_signal(SIGFPE, "sig_handler");
pcntl_signal(SIGHUP, "sig_handler");
// pcntl_signal(SIGINT, "sig_handler");
pcntl_signal(SIGQUIT, "sig_handler");
pcntl_signal(SIGILL, "sig_handler");
pcntl_signal(SIGTRAP, "sig_handler");
pcntl_signal(SIGABRT, "sig_handler");
pcntl_signal(SIGIOT, "sig_handler");
pcntl_signal(SIGBUS, "sig_handler");
pcntl_signal(SIGPOLL, "sig_handler");
pcntl_signal(SIGSYS, "sig_handler");
pcntl_signal(SIGCONT, "sig_handler");
pcntl_signal(SIGUSR1, "sig_handler");
pcntl_signal(SIGUSR2, "sig_handler");
pcntl_signal(SIGSEGV, "sig_handler");
pcntl_signal(SIGPIPE, "sig_handler");
pcntl_signal(SIGALRM, "sig_handler");
pcntl_signal(SIGTERM, "sig_handler");
pcntl_signal(SIGSTKFLT, "sig_handler");
pcntl_signal(SIGCHLD, "sig_handler");
pcntl_signal(SIGCLD, "sig_handler");
pcntl_signal(SIGIO, "sig_handler");
pcntl_signal(SIGTSTP, "sig_handler");
pcntl_signal(SIGTTIN, "sig_handler");
pcntl_signal(SIGTTOU, "sig_handler");
pcntl_signal(SIGURG, "sig_handler");
pcntl_signal(SIGXCPU, "sig_handler");
pcntl_signal(SIGXFSZ, "sig_handler");
pcntl_signal(SIGVTALRM, "sig_handler");
pcntl_signal(SIGPROF, "sig_handler");
pcntl_signal(SIGWINCH, "sig_handler");
pcntl_signal(SIGPWR, "sig_handler");

I commented out SIGNIT, as it is the signal which is sent to your process when you press CTRL-C. If you catch this signal, you must handle it properly:

function sig_handler($signo) {
switch($signo) {
case SIGINT:
// customized cleanup code
exit; // now exit
break;
}
}

Otherwise the only possibility to stop your process is by sending a SIGKILL signal - you can do this on the shell by typing "kill -9 PID" (where -9 is the numerical value for SIGKILL).

Note: You cannot add a handler (i.e. ignore signals) for SIGSTOP and SIGKILL - for obvious reasons.

[email protected]
27-May-2002 10:42

The signal handler pcntl_signal() does not
work if you are waiting for socket connections
with socket_accept(). The signal handler is
installed, but does not do anything if a signal
arrives. Anyone got a solution for that?

keksov[at]gmx.de
29-May-2002 05:10

You have to use socket_select before socket_accept, so your code will wait for connection with select. socket_select can be interrupted by signals easily. Below is an example from my library (methods of class TNetSocket):
//-- select
function select($aread=NULL,$awrite=NULL,$aexcept=NULL,$timeout=NULL)
{
while(1)
{
$res="";
$res=socket_select($aread, $awrite, $aexcept, $timeout);

// if errno===0 it means what select was interrrupted by SysV signal
if($res===false && socket_last_error($this->socket())!==0)
{ // error occured, interrupted not by a signal
$this->set_socket_error(__LINE__);
return(false);
}
break;
}
return(true);
}

//-- accept, wait for incomming connection
function accept()
{
$this->clear_socket_error();
$this->set_io_socket(_SOCKET_);

$socket=$this->socket();
$aread=array($socket);
if ($this->select($a=&$aread)===false)
return(false);

$child_socket=socket_accept($this->socket);
if($child_socket <= 0)
{ // error occured
$this->set_socket_error(__LINE__);
return(false);
}

$this->child_socket=$child_socket;
$this->sockets[_CHILD_SOCKET_]=&$this->child_socket;
$this->set_io_socket(_CHILD_SOCKET_);

$a=&$this->peername;
$res=socket_getpeername($child_socket,$a);

if($res <= 0)
{ // error occured
$this->set_socket_error(__LINE__);
return(false);
}

$this->get_address_and_port(_CHILD_SOCKET_);
TLogManager::phpserv("Connection accepted. ADDRESS $this->address, PORT $this->port","net_socket",__FILE__,__LINE__);

$this->connected=true;
return(true); // return new object of TNetSocket type
}

add a note about notes
previouspg_updatepcntl_execnext
Last updated: Fri, 30 Aug 2002
show source | credits | stats | mirror sites
Copyright © 2001, 2002 The PHP Group
All rights reserved.
This mirror generously provided by:
Last updated: Wed Sep 4 00:18:56 2002 CEST