php管道通信
本人博客:http://www.cnblogs.com/nickbai/
本人GitHub:https://github.com/nick-bai
php進(jìn)行進(jìn)程間通信的方式有好幾種:消息隊(duì)列,管道,共享內(nèi)存,socket,信號(hào)。本文介紹的是通過(guò)有名管道的方式。
管道PIPE
管道用于承載簡(jiǎn)稱(chēng)之間的通訊數(shù)據(jù)。為了方便理解,可以將管道比作文件,進(jìn)程A將數(shù)據(jù)寫(xiě)到管道P中,然后進(jìn)程B從管道P中讀取數(shù)據(jù)。php提供的管道操作API與操作文件的API基本一樣,除了創(chuàng)建管道使用posix_mkfifo函數(shù),讀寫(xiě)等操作均與文件操作函數(shù)相同。當(dāng)然,你可以直接使用文件模擬管道,但是那樣無(wú)法使用管道的特性了。
通過(guò)管道通信的大概思路是,首先創(chuàng)建一個(gè)管道,然后子進(jìn)程向管道中寫(xiě)入信息,父進(jìn)程從管道中讀取信息,這樣就可以做到父子進(jìn)程直接實(shí)現(xiàn)通信了。<?php<br>/**<br>?*?author:?NickBai<br>?*?createTime:?2016/12/2?0002?上午?11:12<br>?*/<br>//創(chuàng)建管道<br>$pipePath?=?"/tmp/test.pipe";<br>if(?!file_exists(?$pipePath?)?){<br>????if(?!posix_mkfifo(?$pipePath,?0666?)?){<br>????????exit('make?pipe?false!'?.?PHP_EOL);<br>????}<br>}<br><br>//創(chuàng)建進(jìn)程,子進(jìn)程寫(xiě)管道,父進(jìn)程讀管道<br>$pid?=?pcntl_fork();<br><br>if(?$pid?==?0?){<br>????//子進(jìn)程寫(xiě)管道<br>????$file?=?fopen(?$pipePath,?'w'?);<br>????fwrite(?$file,?'hello?world'?);<br>????sleep(1);<br>????exit();<br>}else{<br>????//父進(jìn)程讀管道<br>????$file?=?fopen(?$pipePath,?'r'?);<br>????//stream_set_blocking(?$file,?False?);??//設(shè)置成讀取非阻塞<br>????echo?fread(?$file,?20?)?.?PHP_EOL;<br><br>????pcntl_wait($status);??//回收子進(jìn)程<br>}
? ? ?注意:本代碼只能在linux下運(yùn)行,并且只能在php-cli模式下。
第7行:指定一個(gè)管道的路徑,這里跟普通文件沒(méi)什么區(qū)別。
第9行:通過(guò) posix_mkfifo 函數(shù)創(chuàng)建 管道 并且設(shè)置讀寫(xiě)權(quán)限為 0666
第15行:通過(guò) pcntl_fork函數(shù)創(chuàng)建一個(gè)子進(jìn)程。注意從現(xiàn)在開(kāi)始,程序?qū)?huì)被分成兩個(gè)進(jìn)程來(lái)執(zhí)行。 pcntl_fork 函數(shù) 很特殊,它調(diào)用一次擁有 多個(gè)返回值。在父進(jìn)程中:它返回 子進(jìn)程的ID 這個(gè)值是 大于0 的。在子進(jìn)程中,它返回0。當(dāng)返回 -1 時(shí)表示創(chuàng)建進(jìn)程失敗。
? 第17行:兩個(gè)進(jìn)程根據(jù)當(dāng)前進(jìn)程所獲得的$pid的值不同,而進(jìn)入不同的分支。
?第18~22行:子進(jìn)程打開(kāi)管道,并向其中寫(xiě)入hello world ,然后進(jìn)入休眠,休眠結(jié)束之后,退出。
?第25~29行:父進(jìn)程打開(kāi)管道,并進(jìn)行讀取,最后執(zhí)行 29行的代碼回收掉子進(jìn)程。這里面兩個(gè)地方是阻塞的,首先是默認(rèn)讀的地方,要等待子進(jìn)程發(fā)出exit命令之后,才能返回?cái)?shù)據(jù)。還有就是回收進(jìn)程的 pcntl_wait方法。要等到進(jìn)程退出。
?在linux 下運(yùn)行該代碼:
會(huì)看到程序阻塞 1秒 之后,輸出 hello world。
當(dāng)我們打開(kāi) 第 26 行代碼,并將 27行改為 var_dump(fread( $file, 20 )) . PHP_EOL; 時(shí),運(yùn)行程序:
能看到程序立馬輸出 空串,并等待 1秒 中之后退出。這是因?yàn)椤.?dāng)讀取是非阻塞的情況下,父進(jìn)程進(jìn)行讀取信息的時(shí)候,不會(huì)等待立馬有信息,管道中沒(méi)有信息,也會(huì)立馬返回。然后執(zhí)行到 29行回收子進(jìn)程的時(shí)候,阻塞等待子進(jìn)程退出后結(jié)束。
下面來(lái)看一個(gè)簡(jiǎn)單的實(shí)際小例子。兩個(gè)子進(jìn)程向一個(gè)文件中寫(xiě)信息,父進(jìn)程負(fù)責(zé)監(jiān)聽(tīng)檢測(cè)這個(gè)文件是否寫(xiě)入完成,完成之后,講這個(gè)文件copy一份。這里,父子進(jìn)程之間通過(guò)管道通信,確認(rèn)是否完成寫(xiě)入。<?php<br>/**<br>?*?author:?NickBai<br>?*?createTime:?2016/12/2?0002?下午?2:00<br>?*/<br>//創(chuàng)建管道<br>$pipePath?=?"/tmp/test.pipe";<br>if(?!file_exists(?$pipePath?)?){<br>????if(?!posix_mkfifo(?$pipePath,?0666?)?){<br>????????exit("make?pipe?fail?\n");<br>????}<br>}<br><br>//創(chuàng)建兩個(gè)子進(jìn)程寫(xiě)文件<br>for(?$i?=?0;?$i?<?2;?$i++?){<br><br>????$pid?=?pcntl_fork();<br>????if(?$pid?==?0?){<br>????????file_put_contents(?'./pipe.log',?$i?.?"?write?pipe\n",?FILE_APPEND?);??//寫(xiě)入文件<br>????????$file?=?fopen(?$pipePath,?'w'?);<br>????????fwrite(?$file,?$i?.?"\n"?);??//向管道中寫(xiě)標(biāo)識(shí),標(biāo)識(shí)寫(xiě)入完畢。<br>????????fclose(?$file?);<br>????????exit();??//退出子進(jìn)程<br>????}<br>}<br><br>//父進(jìn)程要做的是:<br>//1、讀取管道中的寫(xiě)出狀態(tài),判斷是否完全寫(xiě)完<br>//2、拷貝寫(xiě)好的文件<br>//3、刪除管道<br>//4、回收進(jìn)程<br><br>$file?=?fopen(?$pipePath,?'r'?);<br>$line?=?0;<br>while(1){<br>????$end?=?fread(?$file,?1024?);<br>????foreach(?str_split(?$end?)?as?$c)?{<br>????????if?(?"\n"?==?$c?)?{<br>????????????$line++;<br>????????}<br>????}<br><br>????if(?$line?==?2?){<br>????????copy(?'./pipe.log',?'./pipe_copy.log'?);<br>????????fclose(?$file?);<br>????????unlink(?$pipePath?);<br>????????pcntl_wait(?$status?);<br>????????exit("ok?\n");<br>????}<br>}

熱AI工具

Undress AI Tool
免費(fèi)脫衣服圖片

Undresser.AI Undress
人工智能驅(qū)動(dòng)的應(yīng)用程序,用于創(chuàng)建逼真的裸體照片

AI Clothes Remover
用于從照片中去除衣服的在線(xiàn)人工智能工具。

Clothoff.io
AI脫衣機(jī)

Video Face Swap
使用我們完全免費(fèi)的人工智能換臉工具輕松在任何視頻中換臉!

熱門(mén)文章

熱工具

記事本++7.3.1
好用且免費(fèi)的代碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
功能強(qiáng)大的PHP集成開(kāi)發(fā)環(huán)境

Dreamweaver CS6
視覺(jué)化網(wǎng)頁(yè)開(kāi)發(fā)工具

SublimeText3 Mac版
神級(jí)代碼編輯軟件(SublimeText3)

《Go語(yǔ)言編程實(shí)例:Web開(kāi)發(fā)中的代碼示例》隨著互聯(lián)網(wǎng)的快速發(fā)展,Web開(kāi)發(fā)已經(jīng)成為各行業(yè)中必不可少的一部分。作為一門(mén)功能強(qiáng)大且性能優(yōu)越的編程語(yǔ)言,Go語(yǔ)言在Web開(kāi)發(fā)中越來(lái)越受到開(kāi)發(fā)者們的青睞。本文將通過(guò)具體的代碼示例,介紹如何利用Go語(yǔ)言進(jìn)行Web開(kāi)發(fā),讓讀者能夠更好地理解和運(yùn)用Go語(yǔ)言來(lái)構(gòu)建自己的Web應(yīng)用。1.簡(jiǎn)單的HTTP服務(wù)器首先,讓我們從一個(gè)

華為云邊緣計(jì)算對(duì)接指南:Java代碼示例快速實(shí)現(xiàn)接口隨著物聯(lián)網(wǎng)技術(shù)的快速發(fā)展和邊緣計(jì)算的興起,越來(lái)越多的企業(yè)開(kāi)始關(guān)注邊緣計(jì)算的應(yīng)用。華為云提供了邊緣計(jì)算服務(wù),為企業(yè)提供了高可靠的計(jì)算資源和便捷的開(kāi)發(fā)環(huán)境,使得邊緣計(jì)算應(yīng)用更加容易實(shí)現(xiàn)。本文將介紹如何通過(guò)Java代碼快速實(shí)現(xiàn)華為云邊緣計(jì)算的接口。首先,我們需要準(zhǔn)備好開(kāi)發(fā)環(huán)境。確保你已經(jīng)安裝了Java開(kāi)發(fā)工具包(

了解Python編程的入門(mén)級(jí)代碼示例Python是一種簡(jiǎn)單易學(xué),功能強(qiáng)大的編程語(yǔ)言。對(duì)于初學(xué)者來(lái)說(shuō),了解Python編程的入門(mén)級(jí)代碼示例是非常重要的。本文將為您提供一些具體的代碼示例,幫助您快速入門(mén)。打印HelloWorldprint("HelloWorld")這是Python中最簡(jiǎn)單的代碼示例。print()函數(shù)用于將指定的內(nèi)容輸出

Java冒泡排序最簡(jiǎn)單的代碼示例冒泡排序是一種常見(jiàn)的排序算法,它的基本思想是通過(guò)相鄰元素的比較和交換來(lái)將待排序序列逐步調(diào)整為有序序列。下面是一個(gè)簡(jiǎn)單的Java代碼示例,演示了如何實(shí)現(xiàn)冒泡排序:publicclassBubbleSort{publicstaticvoidbubbleSort(int[]arr){int

如何使用PHP編寫(xiě)庫(kù)存管理系統(tǒng)中的庫(kù)存分倉(cāng)管理功能代碼庫(kù)存管理是許多企業(yè)中不可或缺的一部分。對(duì)于擁有多個(gè)倉(cāng)庫(kù)的企業(yè)來(lái)說(shuō),庫(kù)存分倉(cāng)管理功能尤為重要。通過(guò)合理管理和跟蹤庫(kù)存,企業(yè)可以實(shí)現(xiàn)不同倉(cāng)庫(kù)之間的庫(kù)存調(diào)撥,優(yōu)化運(yùn)營(yíng)成本,改善協(xié)同效率。本文將介紹如何使用PHP編寫(xiě)庫(kù)存分倉(cāng)管理功能的代碼,并為您提供相關(guān)的代碼示例。一、建立數(shù)據(jù)庫(kù)在開(kāi)始編寫(xiě)庫(kù)存分倉(cāng)管理功能的代碼之

PHP變量存儲(chǔ)程序運(yùn)行期間的值,對(duì)于構(gòu)建動(dòng)態(tài)且交互式的WEB應(yīng)用程序至關(guān)重要。本文將深入探討php變量,并通過(guò)10個(gè)真實(shí)的示例展示它們的實(shí)際應(yīng)用。1.存儲(chǔ)用戶(hù)輸入$username=$_POST["username"];$passWord=$_POST["password"];此示例從表單提交中提取用戶(hù)名和密碼,并將其存儲(chǔ)在變量中以供進(jìn)一步處理。2.設(shè)置配置值$database_host="localhost";$database_username="username";$database_pa

Java選擇排序法代碼編寫(xiě)指南及示例選擇排序是一種簡(jiǎn)單直觀(guān)的排序算法,其思想是每次從未排序的元素中選擇最?。ɑ蜃畲螅┑脑剡M(jìn)行交換,直到所有元素排序完成。本文將提供選擇排序的代碼編寫(xiě)指南,并附上具體的Java示例代碼。算法原理選擇排序的基本原理是將待排序數(shù)組分為已排序和未排序兩部分,每次從未排序部分選擇最小(或最大)的元素,將其放到已排序部分的末尾。重復(fù)上述

標(biāo)題:從入門(mén)到精通:Go語(yǔ)言中常用數(shù)據(jù)結(jié)構(gòu)的代碼實(shí)現(xiàn)數(shù)據(jù)結(jié)構(gòu)在編程中起著至關(guān)重要的作用,它是程序設(shè)計(jì)的基礎(chǔ)。在Go語(yǔ)言中,有許多常用的數(shù)據(jù)結(jié)構(gòu),掌握這些數(shù)據(jù)結(jié)構(gòu)的實(shí)現(xiàn)方式對(duì)于成為一名優(yōu)秀的程序員至關(guān)重要。本文將介紹Go語(yǔ)言中常用的數(shù)據(jù)結(jié)構(gòu),并給出相應(yīng)的代碼示例,幫助讀者從入門(mén)到精通這些數(shù)據(jù)結(jié)構(gòu)。1.數(shù)組(Array)數(shù)組是一種基本的數(shù)據(jù)結(jié)構(gòu),是一組相同類(lèi)型
