English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
Comunicazione tramite segnali. È possibile visualizzare i tipi di segnali attualmente disponibili nel sistema con kill -l
Per dettagli su ciascun segnale, consultare questo mio articolo: https://it.oldtoolbag.com/article/106040.htm
Quando si utilizza un segnale, è possibile controllare la versione corrente di PHP tramite php --version. È stato deciso quale metodo utilizzare per la comunicazione tra processi.
[root@roverliang ipc]# php --version PHP 5.6.24 (cli) (costruito: 15 ago 2016 19:14:02) Copyright (c) 1997-2016 The PHP Group Zend Engine v2.6.0, Copyright (c) 1998-2016 Zend Technologies
E' necessario utilizzare la funzione pcntl_signal_dispatch per PHP versione (PHP 5 >= 5.3.0, PHP 7)
Se la versione di PHP è inferiore a 5.3, alcune grandi aziende potrebbero essere inferiori a questa versione. In questo caso, viene utilizzato declare(ticks=1), il che significa che ogni volta che viene eseguito un istruzione di basso livello,
verrà controllato se è apparso il segnale. Per ulteriori informazioni, vedere https://it.oldtoolbag.com/article/48340.htm
L'esplicazione ufficiale è la seguente: Tick (periodo di clock) è un evento che si verifica ogni volta che l'interprete esegue N istruzioni di basso livello contabili all'interno di un segmento declare. Il valore di N è specificato nella sezione directive di declare con ticks=N.
Allora cosa sono le istruzioni di basso livello? Come mostrato nel codice seguente:
for ($i = 0; $i < 3; $i++) { echo $i.PHP_EOL; }
Quindi questo ciclo for contiene tre istruzioni di basso livello. Ogni volta che viene outputto $i, viene controllato se è accaduto un evento registrato. Si può immaginare che l'efficienza sia relativamente bassa. Quindi se si rileva che la versione di PHP è maggiore o uguale a 5.3, si utilizza pcntl_signal_dispatch per effettuare la distribuzione dei segnali.
Il processo principale registra alcune funzioni di gestione dei segnali durante l'avvio.
/** * @param $signal segnale */ function signalHandal($signal) { switch ($signal) { case SIGINT: //do something break; case SIGHUP: //do something break; default : //do something break; } }
然后将信号处理器与信号处理函数绑定:
//根据不同的信号,安装不同的信号处理器 pcntl_signal(SIGINT, 'signalHandal'); pcntl_signal(SIGHUP, 'signalHandal'); pcntl_signal(SIGUSR1, 'signalHandla');
在子进程中监听信号,如果出现该信号,就调用预安装的信号处理函数
//分配信号。 pcntl_signal_dispatch($signal);
让我们整理一下思路:
1、定义信号发生时需要处理的函数
2、将信号与信号处理函数绑定,称为信号安装。
3、监听或分发信号,出现信号调用已安装的信号处理程序。
Comprendere bene i concetti di segnali sopra, vediamo un demo:
<?php $parentpid = posix_getpid(); echo "Progresso del genitore pid:{$parentpid}\n"; //Definire una funzione gestore di segnali function sighandler($signal) { if ($signal == SIGINT) { $pid = getmypid(); exit("{$pid} processo, Ucciso!".PHP_EOL); } } //php version < 5.3 .Ogni volta che esegue un comando di basso livello, verifica se è stato emesso questo segnale. La perdita di efficienza è molto grande. //declare(ticks=1); $child_list = []; //Registrare un gestore di segnali. Quando viene emesso questo segnale, viene chiamata la funzione definita pcntl_signal(SIGINT, 'sighandler'); for($i = 0; $i < 3; $i++) { $pid = pcntl_fork(); if ($pid == 0) { //Sottoprocédure while (true) { //Chiamare il gestore di segnali installato per verificare se ci sono nuovi segnali in attesa di dispatching pcntl_signal_dispatch(); echo "Sono il figlio: ".getmypid(). " e sto eseguendo !".PHP_EOL; sleep(rand(1,3)); } } $child_list[] = $pid; } else { die('fork fall!'.PHP_EOL); } } sleep(5); foreach ($child_list as $key => $pid) { posix_kill($pid, SIGINT); } sleep(2); echo "{$parentpid} genitore è finito".PHP_EOL;