In diesem Artikel erfahren Sie mehr über den Prozess und die Kommunikation zwischen Prozessen in PHP. Es hat einen gewissen Referenzwert. Freunde in Not können sich darauf beziehen. Ich hoffe, es wird für alle hilfreich sein.
Umgebung
Der Prozess in PHP wird in Form von Erweiterungen abgeschlossen. Durch diese Erweiterungen können wir eine Reihe von Aktionen im Prozess problemlos abschließen.
pcntl-Erweiterung: Die Hauptprozesserweiterung, der Abschlussprozess wird im Wartevorgang erstellt. Posix-Erweiterung: Vollständige allgemeine API der Posix-kompatiblen Maschine, z. B. zum Abrufen der Prozess-ID, zum Beenden des Prozesses usw. sysvmsg-Erweiterung: Nachrichtenwarteschlange, die die Kommunikation zwischen Prozessen im System-V-Modus implementiert. sysvsem-Erweiterung: implementiert Semaphore im System-V-Modus. sysvshm-Erweiterung: implementiert gemeinsam genutzten Speicher im System-V-Modus. Sockets-Erweiterung: Implementiert die Socket-Kommunikation. Diese Erweiterungen können nur unter Linux/Mac verwendet werden und werden unter Windows nicht unterstützt. Abschließend wird empfohlen, dass die PHP-Version 5.5+ ist.
Einfaches Beispiel
Ein einfaches PHP-Mehrprozessbeispiel In diesem Beispiel gibt es einen untergeordneten Prozess und einen übergeordneten Prozess. Der untergeordnete Prozess gibt fünfmal aus und beendet das Programm.
echo "parent progress pid:{$parentPid}\n"; $childList = array(); $pid = pcntl_fork(); if ( $pid == -1) { // 创建失败 exit("fork progress error!\n"); } else if ($pid == 0) { // 子进程执行程序 $pid = posix_getpid(); $repeatNum = 5; for ( $i = 1; $i <= $repeatNum; $i++) { echo "({$pid})child progress is running! {$i} \n"; $rand = rand(1,3); sleep($rand); } exit("({$pid})child progress end!\n"); } else { // 父进程执行程序 $childList[$pid] = 1; } // 等待子进程结束 pcntl_wait($status); echo "({$parentPid})main progress end!";
Perfekt, endlich einen untergeordneten Prozess und einen übergeordneten Prozess erstellt. Ist es vorbei? Nein, jeder Prozess ist unabhängig voneinander, es gibt keine Schnittmenge und der Anwendungsbereich ist stark eingeschränkt. Was tun? Nutzen wir die Interprogress-Kommunikation.
Interprozesskommunikation (IPC)
Zu den Prozesskommunikationsmethoden in Linux gehören normalerweise: Nachrichtenwarteschlange, Semaphor, gemeinsam genutzter Speicher, Signal, Pipe und Socket.
1. Nachrichtenwarteschlange
Die Nachrichtenwarteschlange ist eine im Speicher gespeicherte Warteschlange. Der folgende Code erstellt drei Produzenten-Unterprozesse und zwei Verbraucher-Unterprozesse. Diese 5 Prozesse kommunizieren über die Nachrichtenwarteschlange.
echo "parent progress pid:{$parentPid}\n";$childList = array(); // 创建消息队列,以及定义消息类型(类似于数据库中的库) $id = ftok(__FILE__,'m'); $msgQueue = msg_get_queue($id); const MSG_TYPE = 1; // 生产者 function producer(){ global $msgQueue; $pid = posix_getpid(); $repeatNum = 5; for ( $i = 1; $i <= $repeatNum; $i++) { $str = "({$pid})progress create! {$i}"; msg_send($msgQueue,MSG_TYPE,$str); $rand = rand(1,3); sleep($rand); } } // 消费者 function consumer(){ global $msgQueue; $pid = posix_getpid(); $repeatNum = 6; for ( $i = 1; $i <= $repeatNum; $i++) { $rel = msg_receive($msgQueue,MSG_TYPE,$msgType,1024,$message); echo "{$message} | consumer({$pid}) destroy \n"; $rand = rand(1,3); sleep($rand); } } function createProgress($callback){ $pid = pcntl_fork(); if ( $pid == -1) { // 创建失败 exit("fork progress error!\n"); } else if ($pid == 0) { // 子进程执行程序 $pid = posix_getpid(); $callback(); exit("({$pid})child progress end!\n"); }else{ // 父进程执行程序 return $pid; } } // 3个写进程 for ($i = 0; $i < 3; $i ++ ) { $pid = createProgress('producer'); $childList[$pid] = 1; echo "create producer child progress: {$pid} \n"; } // 2个写进程 for ($i = 0; $i < 2; $i ++ ) { $pid = createProgress('consumer'); $childList[$pid] = 1; echo "create consumer child progress: {$pid} \n"; } // 等待所有子进程结束 while(!empty($childList)){ $childPid = pcntl_wait($status); if ($childPid > 0){ unset($childList[$childPid]); } } echo "({$parentPid})main progress end!\n";
Da nur ein Prozess auf die Daten in der Nachrichtenwarteschlange zugreifen kann, sind keine zusätzlichen Sperren oder Semaphoren erforderlich.
2. Semaphor und gemeinsamer Speicher
Semaphor: Es handelt sich um eine vom System bereitgestellte atomare Operation, die nur von Ihrem Prozess gleichzeitig ausgeführt werden kann. Wenn ein Prozess ein Semaphor erhält, muss es vom Prozess freigegeben werden.
Gemeinsamer Speicher: Es handelt sich um einen vom System geöffneten Speicherbereich. Jeder Prozess kann gleichzeitig auf diesen Bereich zugreifen, um die Konsistenz der Daten sicherzustellen Lock oder Semaphor sein.
Erstellen Sie unten mehrere Prozesse, um denselben Wert im Speicher zu ändern.
echo "parent progress pid:{$parentPid}\n"; $childList = array(); // 创建共享内存,创建信号量,定义共享key $shm_id = ftok(__FILE__,'m'); $sem_id = ftok(__FILE__,'s'); $shareMemory = shm_attach($shm_id); $signal = sem_get($sem_id); const SHARE_KEY = 1; // 生产者 function producer(){ global $shareMemory; global $signal; $pid = posix_getpid(); $repeatNum = 5; for ( $i = 1; $i <= $repeatNum; $i++) { // 获得信号量 sem_acquire($signal); if (shm_has_var($shareMemory,SHARE_KEY)){ // 有值,加一 $count = shm_get_var($shareMemory,SHARE_KEY); $count ++; shm_put_var($shareMemory,SHARE_KEY,$count); echo "({$pid}) count: {$count}\n"; }else{ // 无值,初始化 shm_put_var($shareMemory,SHARE_KEY,0); echo "({$pid}) count: 0\n"; } // 用完释放 sem_release($signal); $rand = rand(1,3); sleep($rand); } } function createProgress($callback){ $pid = pcntl_fork(); if ( $pid == -1) { // 创建失败 exit("fork progress error!\n"); } else if ($pid == 0) { // 子进程执行程序 $pid = posix_getpid(); $callback(); exit("({$pid})child progress end!\n"); }else{ // 父进程执行程序 return $pid; } } // 3个写进程 for ($i = 0; $i < 3; $i ++ ) { $pid = createProgress('producer'); $childList[$pid] = 1; echo "create producer child progress: {$pid} \n"; } // 等待所有子进程结束 while(!empty($childList)){ $childPid = pcntl_wait($status); if ($childPid > 0){ unset($childList[$childPid]); } } // 释放共享内存与信号量 shm_remove($shareMemory); sem_remove($signal); echo "({$parentPid})main progress end!\n";
3. Signal
Ein Signal ist ein Systemaufruf. Normalerweise besteht der von uns verwendete Kill-Befehl darin, ein bestimmtes Signal an einen bestimmten Prozess zu senden. Sie können die spezifischen Signale überprüfen, indem Sie kill -l in liunx/mac ausführen. Im folgenden Beispiel wartet der übergeordnete Prozess 5 Sekunden und sendet das Signatursignal an den untergeordneten Prozess. Der untergeordnete Prozess erfasst das Signal und verarbeitet es mit der Signalverarbeitungsfunktion.
echo "parent progress pid:{$parentPid}\n"; // 定义一个信号处理函数 function sighandler($signo) { $pid = posix_getpid(); echo "{$pid} progress,oh no ,I'm killed!\n"; exit(1); } $pid = pcntl_fork(); if ( $pid == -1) { // 创建失败 exit("fork progress error!\n"); } else if ($pid == 0) { // 子进程执行程序 // 注册信号处理函数 declare(ticks=10); pcntl_signal(SIGINT, "sighandler"); $pid = posix_getpid(); while(true){ echo "{$pid} child progress is running!\n"; sleep(1); } exit("({$pid})child progress end!\n"); }else{ // 父进程执行程序 $childList[$pid] = 1; // 5秒后,父进程向子进程发送sigint信号. sleep(5); posix_kill($pid,SIGINT); sleep(5); } echo "({$parentPid})main progress end!\n";
4. Pipes (benannte Pipes)
Pipes werden in unbenannte Pipes unterteilt, und benannte Pipes können nur für die Kommunikation zwischen Prozessen verwendet werden , während bekannte Pipes für jeden Prozess auf demselben Host verwendet werden können. Hier werden nur bekannte Sender vorgestellt. Im folgenden Beispiel schreibt der untergeordnete Prozess Daten und der übergeordnete Prozess liest Daten.
$pipe_path = '/data/test.pipe'; if(!file_exists($pipe_path)){ if(!posix_mkfifo($pipe_path,0664)){ exit("create pipe error!"); } } $pid = pcntl_fork(); if($pid == 0){ // 子进程,向管道写数据 $file = fopen($pipe_path,'w'); while (true){ fwrite($file,'hello world'); $rand = rand(1,3); sleep($rand); } exit('child end!'); }else{ // 父进程,从管道读数据 $file = fopen($pipe_path,'r'); while (true){ $rel = fread($file,20); echo "{$rel}\n"; $rand = rand(1,2); sleep($rand); } }
Empfohlenes Lernen: „PHP-Video-Tutorial“
Das obige ist der detaillierte Inhalt vonErfahren Sie in einem Artikel mehr über Prozesse und prozessübergreifende Kommunikation in PHP. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!