|
|
LXXXI. Contr�le des processus
Le gestionnaire de contr�le des processus n'est pas activ� par d�faut.
Il faut utiliser l'option de configuration
--enable-pcntl
lors de la compilation de PHP pour l'activer.
La liste suivante rassemble tous les signaux qui sont actuellement
support�s par les fonctions de gestion des processus de PHP. Reportez
vous � votre manuel pour plus de d�tails sur les comportements de ces
signaux.
Tableau 1. Signaux support�s SIG_IGN | SIGFPE | SIGCONT | SIG_DFL | SIGKILL | SIGSTOP | SIG_ERR | SIGUSR1 | SIGTSTP | SIGHUP | SIGUSR2 | SIGTTIN | SIGINT | SIGSEGV | SIGTTOU | SIGQUIT | SIGPIPE | SIGURG | SIGILL | SIGALRM | SIGXCPU | SIGTRAP | SIGTERM | SIGXFSZ | SIGABRT | SIGSTKFLT | SIGVTALRM | SIGIOT | SIGCHLD | SIGPROF | SIGBUS | SIGCLD | SIGWINCH | SIGPOLL | SIGIO | SIGPWR | SIGSYS | | |
Cet exemple effectue un fork du processus d�mon gr�ce � un gestionnaire de
signaux.
Exemple 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
}
}
?< |
|
- Table des mati�res
- pcntl_exec --
Executes specified program in current process space
- pcntl_fork -- Forks the currently running process
- pcntl_signal -- Installe un gestionnaire de signaux
- pcntl_waitpid -- Attend la fin de l'ex�cution d'un processus fils
- pcntl_wexitstatus --
Retourne le code d'un processus fils termin�
- pcntl_wifexited --
Retourne TRUE si le code de retour repr�sente une fin normale
- 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 Contr�le des processus |
|
[email protected]
22-Feb-2002 09: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 09: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 09: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 04: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 }
|
|
|
| |