Heim  >  Artikel  >  Backend-Entwicklung  >  Wie PHP mit Prozesssignalen umgeht (mit Beispielen)

Wie PHP mit Prozesssignalen umgeht (mit Beispielen)

不言
不言nach vorne
2018-09-28 16:05:302574Durchsuche

Der Inhalt dieses Artikels befasst sich mit der Verarbeitung von Prozesssignalen durch PHP. Ich hoffe, dass er für Sie hilfreich ist.

php verfügt über eine Reihe von Prozesssteuerungsfunktionen PCNTL, die es PHP ermöglichen, untergeordnete Prozesse zu erstellen, die exec-Funktion zum Ausführen von Programmen zu verwenden, Signale zu verarbeiten und andere Funktionen wie c in *nix-Systemen zu verwenden.

Hinweis: Die pcntl-Erweiterung ist nur im CLI/CGI-Modus verfügbar. Nicht verfügbar in mod_php und php-fpm. Verwenden Sie diese Funktionen nicht in einer Webserverumgebung, da dies zu unvorhersehbaren Ergebnissen führt. Darüber hinaus verfügt Windows als nicht-Unix-ähnliches System nicht über diese Funktionen.

PCNTL verwendet Ticks als Signal-Handle-Rückrufmechanismus, der die Belastung bei der Verarbeitung asynchroner Ereignisse minimieren kann. Was sind Zecken? Tick ​​ist ein Ereignis, das jedes Mal auftritt, wenn der Interpreter N Low-Level-Anweisungen in einem Codesegment ausführt. Dieses Codesegment muss durch Deklarieren angegeben werden.

Das Folgende ist ein Beispiel für das Senden eines SIGALRM-Signals alle 5 Sekunden, das Abrufen durch die signal_handler-Funktion und das anschließende Drucken eines „Caught SIGALRM“:

<?php   
        declare(ticks = 1);   
      
        function signal_handler($signal) {   
            print "Caught SIGALRM/n";   
            pcntl_alarm(5);   
        }   
      
        pcntl_signal(SIGALRM, "signal_handler", true);   
        pcntl_alarm(5);   
      
        while(true){

        }
      
    ?>

Tatsächlich ist die Leistung des Das offizielle pcntl_signal ist äußerst schlecht, hauptsächlich weil PHP-Funktionen nicht direkt in den Signaleinstellungen des Betriebssystems registriert werden können und das pcntl-Signal daher auf dem Tick-Mechanismus basieren muss. Das Implementierungsprinzip von pcntl_signal besteht darin, das Signal nach dem Auslösen des Signals einer Warteschlange hinzuzufügen. Überprüfen Sie dann kontinuierlich, ob in der Ticks-Callback-Funktion ein Signal vorhanden ist. Führen Sie die in PHP angegebene Callback-Funktion aus. Wenn nicht, verlassen Sie die Funktion. ticks=1 bedeutet, dass diese Funktion jedes Mal zurückgerufen wird, wenn eine Zeile PHP-Code ausgeführt wird. Tatsächlich wird die meiste Zeit kein Signal generiert, aber die Ticks-Funktion wird immer ausgeführt. Ein besserer Ansatz besteht darin, Häkchen zu entfernen und stattdessen pcntl_signal_dispatch zu verwenden, um das Signal selbst in der Codeschleife zu verarbeiten.

Implementierung von pcntl_signal_dispatch

<?php
// 定义一个处理器,接收到SIGINT信号后只输出一行信息
function signalHandler($signo) {
    switch ($signo) {
        case SIGUSR1: echo "SIGUSR1\n"; break;
        case SIGUSR2: echo "SIGUSR2\n"; break;
        default:      echo "unknow";    break;
    }
}

//安装信号触发器器
pcntl_signal(SIGINT, &#39;signalHandler&#39;);
while (true) {
    sleep(1);
    posix_kill(posix_getpid(), SIGUSR1);///向当前进程发送SIGUSR1信号
    pcntl_signal_dispatch(); //接收到信号时,调用注册的signalHandler()
}

PCNTL-Funktionen:

Signalverarbeitung

int pcntl_alarm ( int $seconds )

Stellen Sie einen Zähler ein, um das SIGALRM-Signal nach $seconds Sekunden zu senden

bool pcntl_signal(int $signo ,callback $handler [,bool $restart_syscalls=true])

Legen Sie eine Rückruffunktion für $signo fest, um das Signal zu verarbeiten

Der erste Parameter ist die Signalnummer Der zweite Parameter ist die PHP-Funktion, die beim Auftreten des Signals zurückgerufen werden soll. Der dritte Parameter ist, ob ein Neustart durchgeführt und dieses Signal erneut registriert werden soll. Wenn dieser Parameter falsch ist, wird dieses Signal nur einmal registriert und verarbeitet.

Hinweis: Jeder Aufruf von pcntl_alarm() bricht das zuvor eingestellte Alarmsignal und die Sleep()-Funktion ab.

Das Folgende ist ein Beispiel für das Senden eines SIGALRM-Signals alle 5 Sekunden, das Abrufen durch die signal_handler-Funktion und das anschließende Drucken eines „Caught SIGALRM“:

<?php   
        declare(ticks = 1);   
      
        function signal_handler($signal) {   
            print "Caught SIGALRM/n";   
            pcntl_alarm(5);   
        }   
      
        pcntl_signal(SIGALRM, "signal_handler", true);   
        pcntl_alarm(5);   
      
        for(;;) {   
        }   
      
    ?>

Führen Sie das Programm aus

void pcntl_exec ( string $path [, array $args [, array $envs ]] )

Führen Sie das angegebene Programm im aktuellen Prozessraum aus, ähnlich der Exec-Familienfunktion in C. Der sogenannte aktuelle Bereich ist der Bereich, in den der Code des angegebenen Programms geladen wird und den aktuellen Prozess überschreibt. Der Prozess endet, wenn das Programm ausgeführt wird.

<?php   
    $dir = &#39;/home/test/&#39;;   
    $cmd = &#39;ls&#39;;   
    $option = &#39;-l&#39;;   
    $pathtobin = &#39;/bin/ls&#39;;   
      
    $arg = array($cmd, $option, $dir);   
      
    pcntl_exec($pathtobin, $arg);   
    echo &#39;123&#39;;    //不会执行到该行   
    ?>

Prozess erstellen

int pcntl_fork ( void ) 为当前进程创建一个子进程
int pcntl_wait ( int &$status [, int $options ] ) 阻塞当前进程,只到当前进程的一个子进程退出或者收到一个结束当前进程的信号。 
int pcntl_waitpid ( int $pid , int &$status [, int $options ] ) 功能同pcntl_wait,区别为waitpid为等待指定pid的子进程。当pid为-1时pcntl_waitpid与pcntl_wait一样。

Die Statusinformationen des untergeordneten Prozesses werden in $status in den Funktionen pcntl_wait und pcntl_waitpid gespeichert. Dieser Parameter kann für pcntl_wifexited und pcntl_wifstopped verwendet werden , pcntl_wifsignaled, pcntl_wexitstatus, pcntl_wtermsig, pcntl_wstopsig, pcntl_waitpid Funktionen.

Zum Beispiel

<?php   
    $pid = pcntl_fork();   
    if($pid) { 
        pcntl_wait($status);   
        $id = getmypid();   
        echo "parent process,pid {$id}, child pid {$pid}/n";   
    } else {   
        $id = getmypid();   
        echo "child process,pid {$id}/n";   
        sleep(2);   
    }   
    ?>

Der untergeordnete Prozess schläft 2 Sekunden lang, bevor er nach der Ausgabe von Wörtern wie „untergeordneter Prozess“ beendet wird, während der übergeordnete Prozess blockiert, bis der untergeordnete Prozess beendet wird, bevor er weiter ausgeführt wird.

Prozesspriorität

int pcntl_getpriority ([ int $pid [, int $process_identifier ]] ) 取得进程的优先级,即nice值,默认为0。不同的系统类型以及内核版本下 优先级可能不同(手册中为-20到20)
bool pcntl_setpriority ( int $priority [, int $pid [, int $process_identifier ]] ) 设置进程的优先级

Das obige ist der detaillierte Inhalt vonWie PHP mit Prozesssignalen umgeht (mit Beispielen). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:cnblogs.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen