首頁  >  文章  >  php教程  >  php進程間通訊--有名管道

php進程間通訊--有名管道

PHP中文网
PHP中文网原創
2016-12-05 13:27:452254瀏覽

php管線通訊
本人部落格:http://www.cnblogs.com/nickbai/
本人GitHub:https://github.com/nick-bai

php進行進程間通訊的方式有好幾種:訊息隊列,管道,共享內存,socket,信號。本文介紹的是透過有名管道的方式。  

  管道PIPE

  管道用於承載簡稱之間的通訊資料。為了方便理解,可以將管道比喻為文件,進程A將資料寫到管道P中,然後進程B從管道P中讀取資料。 php提供的管道操作API與操作文件的API基本上一樣,除了建立管道使用posix_mkfifo函數,讀寫等操作都與檔案操作函數相同。當然,你可以直接使用檔案模擬管道,但是那樣無法使用管道的特性了。

  透過管道通訊的大概思路是,首先創建一個管道,然後子進程向管道中寫入信息,父進程從管道中讀取信息,這樣就可以做到父子進程直接實現通信了。 <?php <br/>/**<br> * author: NickBai<br> * createTime: 2016/12/2 0002 上午 11:12<br> */<br>//建立管道<br>$pipePath = "/tmp/test.pipe";<br>if( !file_exists( $pipePath  ){<br> p. , 0666 ) ){<br>        exit('make pipe false!' . PHP_EOL);<br>    }<}<br>}<br>處理程序();<br><br>if( $pid == 0 ){<br>    //子程序寫入管道<br>    $file = fopen( $pipePath, 'w' );<br>  1); <br>    exit() ;<br>}else{<br>    //父程式讀取管道<br>    $file = fopen( $pipePath, 'r' );<br>   //stream_set_blocking(F1file)<br> echo fread( $ file, 20 ) . PHP_EOL;<br><br>    pcntl_wait($status);  //回收子程序<br>}<br>      <br>在:本程式碼時只能於<br>  第7行:指定一個管道的路徑,這裡跟普通文件沒什麼區別。   第9行:透過 posix_mkfifo 函數建立 管道 並且設定讀寫權限為 0666

  第15行:透過 pcntl_fork函數建立一個子程序。注意從現在開始,程式將會被分成兩個流程來執行。 pcntl_fork 函數 很特殊,它呼叫一次擁有 多個回傳值。在父進程中:它回傳 子進程的ID 這個值是 大於0 的。在子進程中,它回傳0。當傳回 -1 時表示建立進程失敗。

  第17行:兩個進程依目前進程所獲得的$pid的值不同,而進入不同的分支。

   第18~22行:子進程打開管道,並向其中寫入hello world ,然後進入休眠,休眠結束之後,退出。

   第25~29行:父進程開啟管道,並進行讀取,最後執行 29行的程式碼回收掉子進程。這裡面兩個地方是阻塞的,首先是預設讀的地方,要等待子程序發出exit指令之後,才能回傳資料。還有就是回收進程的 pcntl_wait方法。要等到進程退出。

   在linux 下運行程式碼:


會看到程式阻塞 1秒 之後,輸出 hello world。
php進程間通訊--有名管道  當我們打開第26 行程式碼,並將27行改為var_dump(fread( $file, 20 )) . PHP_EOL; 時,運行程式:


 能看到程式立刻輸出中之後退出。這是因為。當讀取是非阻塞的情況下,父進程進行讀取訊息的時候,不會等待立刻有訊息,管道中沒有訊息,也會立刻回傳。然後執行到 29行回收子程序的時候,阻塞等待子程序退出後結束。
php進程間通訊--有名管道下面來看一個簡單的實際小例子。兩個子進程向一個檔案寫訊息,父進程負責監聽偵測這個檔案是否寫入完成,完成之後,講這個檔案copy一份。這裡,父子進程之間透過管道通信,確認是否完成寫入。
/**
 * author: NickBai * createTime: 2016/12/2 0002 下午 2:00<br> */<br>//建立管道<br>$pipePath = "/tmp/test.pipe";<br>if( !file_exists( $pipePath ) ){<br>    if( !posix_mkfifo( $pipePath, 0666 ) ){  ); }<br>}<br><br>//建立兩個子程序寫入檔案<br>for ( $i = 0; $i <br>    $pid = pcntl_fork(); './pipe.log', $i . " write pipen", FILE_APPEND );  //寫入檔案<br>        $file = fopen( $pipePath, 'w' ); /向管道中寫標識,標識寫入完畢。 <br>        fclose( $file );<br>        exit();  //退出子程序<br>    exit();  //退出子程序<br>   完<br>//2、拷貝寫好的文件<br>//3、刪除管道<br>//4、回收程序<br><br>$file = fopen( $pipePath, 'r' );<br>$line = 0 ){<br>    $end = fread( $file, 1024 );<br>    foreach( str_split( $end ) as ==$c)H <br>            $line++;<br>        }<br>    }<br> ( $line == 2 ){<br>        copy( './pipe.log', './pipe_copy.log' );🎠   $pipePath );<br>        pcntl_wait( $status );<br> exit("ok n");<br>    }<br>}<br><br><br><br><br> <br>

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn