|
|
LXXXI. Process Control FunctionsBevezet�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�nyekAz 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�sokEz a kiterjeszt�s semmilyen konfigur�ci�s
be�ll�t�sokat nem defini�l. Er�forr�s t�pusokEz 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.
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
}
}
?> |
|
User Contributed Notes Process Control Functions |
|
[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 }
|
|
|
| |