phpマルチプロセス、マルチスレッドの実現

17981 ワード

孤児プロセス:親プロセスが終了し、その1つ以上のサブプロセスが実行されている場合、それらのサブプロセスは孤児プロセスになります.孤児プロセスはinitプロセス(プロセス番号1)によって養子縁組され、initプロセスによってステータス収集が完了します.
ゾンビプロセス:forkを使用してサブプロセスを作成するプロセスです.サブプロセスが終了し、親プロセスがwaitまたはwaitpidを呼び出してサブプロセスのステータス情報を取得していない場合、サブプロセスのプロセス記述子はシステムに保存されます.このプロセスを硬直プロセスと呼ぶ.
ゾンビプロセス危害:プロセスがwait/waitpidを呼び出さなければ、保持された情報は解放されず、そのプロセス番号はずっと占有されるが、システムが使用できるプロセス番号は限られており、大量の硬直プロセスが発生すると、使用可能なプロセス番号がないため、システムが新しいプロセスを生成できない.これはゾンビプロセスの危害であり、避けるべきである.いずれのサブプロセス(initを除く)もexit()の後、すぐに消えるのではなく、ゾンビプロセス(Zombie)と呼ばれるデータ構造を残して、親プロセスの処理を待つ.
すでに発生したゾンビプロセス、解決方法:killは親プロセスを落として、それが発生した硬直プロセスは孤児プロセスになって、これらの孤児プロセスはinitプロセスに引き継がれて、initプロセスはwait()これらの孤児プロセスができて、それらが占有したシステムプロセステーブルの中の資源を解放します.
ゾンビプロセスの解決方法
(1)信号機構による
サブプロセスが終了すると親プロセスにSIGCHAL信号が送信され、親プロセスはSIGCHAL信号を処理します.信号処理関数でwaitを呼び出してゾンビ処理プロセスを処理します.
(2)forkは2回『Unix環境高度プログラミング』8.6節で非常に詳細に述べた.原理は、サブプロセスを孤児プロセスにし、親プロセスをinitプロセスにし、initプロセスによってゾンビプロセスを処理することができる.
 
 
 
マルチプロセスとマルチスレッドの比較
次元の比較
マルチプロセス
マルチスレッド
まとめ
データ共有、同期
データ共有が複雑で、IPCを使う必要がある.データは別々で、同期は簡単です
プロセスデータを共有するため、データ共有は簡単ですが、そのため同期が複雑になります.
それぞれに優勢がある
メモリ、CPU
メモリ使用量が多く、切り替えが複雑で、CPU利用率が低い
メモリ使用量が少なく、切り替えが簡単で、CPU利用率が高い
スレッドの優位性
破棄、切り替えの作成
破棄の作成、切り替えが複雑で、速度が遅い
破棄の作成、切り替えが簡単で、高速
スレッドの優位性
プログラミング
プログラミングが簡単で、デバッグが簡単です.
プログラミングが複雑で、デバッグが複雑です
プロセスの優位性
しんらいせい
プロセス間の相互影響なし
スレッドが削除されると、プロセス全体が削除されます.
プロセスの優位性
分散#ブンサン#
マルチコア、マルチマシン分布式に適応する.1台の機械が足りない場合は、複数の機械に拡張するのが簡単です
マルチコア分散に対応
プロセスの優位性
1)破棄優先スレッドを頻繁に作成する必要がある
原因は上の対比を見てください.
この原則の最も一般的な応用はWebサーバーで、1つの接続に来て1つのスレッドを創立して、切れたらスレッドを破棄して、もしプロセスを使うならば、作成と破棄の代価は耐えられません
2)大量計算が必要な優先使用スレッド
大量計算というのは、もちろんCPUを多く消費し、切り替えが頻繁になっている場合にスレッドが最適です.
この原則は画像処理,アルゴリズム処理が最も一般的である.
3)強相関処理用スレッド,弱相関処理用プロセス
強相関、弱相関とは何ですか.理論的には定義が難しいので、簡単な例をあげると分かります.
一般的なサーバでは、メッセージング、メッセージ処理などのタスクを完了する必要があります.「メッセージ送受信」と「メッセージ処理」は弱い関連タスクであり、「メッセージ処理」では「メッセージ復号」、「ビジネス処理」に分けられる可能性があり、この2つのタスクは相対的に相関性が強い.したがって、「メッセージ送受信」と「メッセージ処理」はプロセス設計に分けられ、「メッセージ復号」、「ビジネス処理」はスレッド設計に分けられる.
もちろん、このような区分方式は変わらないわけではなく、実際の状況に応じて調整することもできます.
4)マルチマシン分散用プロセスに拡張する可能性があり、マルチコア分散用スレッド
原因は上の比較を見てください.
5)すべてのニーズを満たす場合、あなたが最もよく知っている、最も得意な方法で
「データ共有、同期」、「プログラミング、デバッグ」、「信頼性」といういくつかの次元のいわゆる「複雑で簡単」をどのように取捨選択すべきかについては、明確な選択方法がないとしか言いようがありません.しかし、私はあなたに1つの選択原則を教えてあげることができます:もしマルチプロセスとマルチスレッドが要求を満たすことができれば、あなたが最もよく知っていて、最も得意なものを選択します. 
注意しなければならないのは、私はこんなに多くの選択原則を与えたが、実際の応用では基本的に「プロセス+スレッド」の結合方式であり、決して本当にそれ以外の誤解に陥らないでください.
 
消費リソース:
カーネルの観点から,プロセスの目的はシステムリソース(CPU時間,メモリなど)を割り当てる基本単位を担当することである.スレッドはプロセスの実行フローであり、CPUのスケジューリングと割り当ての基本単位であり、プロセスよりも独立して実行できる基本単位である.
スレッドは、互いに同じアドレス空間を使用して、ほとんどのデータを共有し、1つのスレッドを起動するのにかかる空間は、1つのプロセスを起動するのにかかる空間よりもはるかに小さく、スレッド間の切り替えに要する時間もプロセス間の切り替えに必要な時間よりもはるかに小さい.統計によると、総じて言えば、1つのプロセスのオーバーヘッドは1つのスレッドのオーバーヘッドの約30倍であり、もちろん、具体的なシステムでは、このデータには大きな違いがある可能性があります.
通信方式:
プロセス間でデータを転送するのは、通信を通じてしかできません.つまり、時間がかかり、不便です.スレッド時間データの大部分は共有されており(スレッド関数内部は共有されていない)、迅速で便利です.しかし、データ同期にはstatic変数に特に注意するロックが必要です.
スレッド自体のメリット:
アプリケーションのレスポンスを向上させる;マルチCPUシステムをより効率的にします.オペレーティングシステムは、スレッド数がCPU数より大きくない場合、異なるスレッドが異なるCPU上で動作することを保証します.
プログラム構造を改善する.1つの長くて複雑なプロセスは、複数のスレッドに分けて、いくつかの独立したまたは半独立した実行部分になることを考慮することができ、このようなプログラムは理解と修正に有利である.
 
1.[コード]PHPはマルチプロセス並列操作を実現する(デーモンプロセスができる)
 1 /**
 2  *     
 3  *         ProcessOpera.php
 4  *  terminal    /usr/local/php/bin/php ProcessOpera.php & 
 5  *      ps aux|grep php
 6  */
 7  
 8  
 9 ProcessOpera("runCode", array(), 8);
10  
11 /**
12  * run Code
13  */
14 function runCode($opt = array()) {
15    //             
16 }
17  
18 /**
19  * $func               
20  * $opt $func        
21  * $pNum  fork      
22  */
23 function ProcessOpera($func, $opts = array(), $pNum = 1) {
24     while(true) {
25         $pid = pcntl_fork();
26         if($pid == -1) {
27             exit("pid fork error");
28         }   
29         if($pid) {
30             static $execute = 0;
31             $execute++;
32             if($execute >= $pNum) {
33                 pcntl_wait($status);
34                 $execute--;
35             }   
36         } else {
37             while(true) {
38                 //somecode
39                 $func($opts);
40                 sleep(1);
41             }   
42             exit(0);
43         }   
44     }   
45 }

 
2.[コード]PHPマルチスレッド操作を実現
 1 class My extends Thread {
 2     protected $name;
 3     public $runing;
 4     function __construct($name){
 5         $this->runing=1;
 6         $this->param=0;
 7         $this->name=$name;
 8     }
 9     public function run() {
10         while($this->runing){
11             if($this->param){
12                 $time=rand(1,5);
13                 echo 'I am thread '.$this->name.',pid: '.$this->getCreatorId().",param: {$this->param},need {$time}s
"; 14 sleep($time); 15 $this->param=0; 16 }else{ 17 echo "Thread {$this->name} waiting...
"; 18 } 19 sleep(1); 20 } 21 } 22 } 23 $pool=array(); 24 $pool[]=new My('a'); 25 $pool[]=new My('b'); 26 $pool[]=new My('c'); 27 // 28 foreach ($pool as $w) { 29 $w->start(); 30 } 31 // 32 unset($w); 33 for($i=1;$i<10;$i++){ 34 $woker_content=$i; 35 while(1){ 36 foreach($pool as $w){ 37 if(!$w->param){ 38 $w->param=$woker_content; 39 echo "Thread {$w->name} empty,put param {$woker_content}.
"; 40 break 2; 41 } 42 } 43 sleep(1); 44 } 45 } 46 47 unset($w); 48 while(count($pool)){ 49 foreach ($pool as $k => $w) { 50 if(!$w->param){ 51 $w->runing=false; 52 unset($pool[$k]); 53 echo "Thread {$w->name} end,exit!
"; 54 } 55 } 56 sleep(1); 57 } 58 59 echo 'All thread end!';

 
転載先:https://www.cnblogs.com/binghuo000/p/php_thread.html