PHP pcntl

pcntl是一個可以利用操作系統(tǒng)的fork系統(tǒng)調(diào)用在PHP中實現(xiàn)多線程的進程控制擴展,當使用fork系統(tǒng)調(diào)用后執(zhí)行的代碼將會是并行的瘫筐。pcntl僅適用于Linux平臺的CLI模式下使用汽绢。

PHP官方?jīng)]有提供多線程的擴展晌坤,在pecl中有一個pthread擴展提供了多線程的特性桌粉,此版本僅在線程安全版本中可用芋膘。

創(chuàng)建子進程pcntl_fork

int pcntl_fork(void)

pcntl_fork函數(shù)執(zhí)行時會在當前進程下創(chuàng)建一個子進程鳞青,子進程與父進程在PID和PPID上會不同霸饲。

子進程會復(fù)制父進程中所有的數(shù)據(jù)、代碼臂拓、狀態(tài)等信息厚脉。當使用pcntl_fork成功創(chuàng)建子進程后,子進程會復(fù)制父進程的代碼和數(shù)據(jù)埃儿。此時父進程和子進程擁有相同的代碼和數(shù)據(jù)器仗。子進程也會復(fù)制父進程的狀態(tài)融涣。

當使用pcntl_fork創(chuàng)建子進程童番,如果成功則會在父進程中將會返回0,在子進程中會返回自身的進程編號PID威鹿。如果創(chuàng)建失敗則返回-1剃斧。

使用pcntl_fork創(chuàng)建的進程只是一個分支節(jié)點,相當于一個標記忽你,父進程完成后子進程會從標記處繼續(xù)執(zhí)行幼东,也就是說在pcntl_fork之后的代碼分別會被父進程和子進程執(zhí)行兩遍,而兩個進程在執(zhí)行過程中得到的返回值卻是不同的科雳,因此才可以分離父子進程執(zhí)行不同的代碼根蟹。

在Linux環(huán)境下可使用ps命令查看進程

<?php
$pid = pcntl_fork();
if($pid > 0){
    //父進程
    exit(0);
}elseif($pid == 0){
    //子進程
    exit(0);
}

多進程和多線程的作用相同,區(qū)別主要在于

  • 多個線程是在同一個進程內(nèi)的糟秘,線程之間可以共享內(nèi)存變量而實現(xiàn)線程間的通信简逮。
  • 線程比進程更加輕量級,進程要比線程更加消耗系統(tǒng)資源尿赚。

多線程存在的問題主要有

  • 線程讀寫變量存在著同步問題需要加鎖
  • 鎖粒度過大會存在性能問題散庶,會導(dǎo)致只有一個線程在運行,其它線程都在等待鎖凌净,也就無法實現(xiàn)并行悲龟。
  • 同時使用多個鎖時邏輯復(fù)雜,一旦某個鎖沒有被正確釋放可能會發(fā)生線程死鎖冰寻。
  • 某個線程發(fā)生致命錯誤會導(dǎo)致整個進程崩潰

相對而言多進程更為穩(wěn)定须教,可利用進程間通信IPC技術(shù)實現(xiàn)數(shù)據(jù)共享。多進程通信的方式主要包括

  • 共享內(nèi)存
    共享內(nèi)存和線程間讀寫變量時一樣的斩芭,都需要加鎖轻腺,同時也存在同步、死鎖等問題秒旋。
  • 消息隊列
    消息隊列采用多個子進程搶占隊列的模式约计,性能較好。
  • 管道迁筛、UnixSock煤蚌、TCP耕挨、UDP
    可以使用read/write來傳遞數(shù)據(jù),TCP/UDP使用socket來通信尉桩,子進程可以分布運行筒占。

利用fork系統(tǒng)調(diào)用可以實現(xiàn)并發(fā)的TCP服務(wù)器,主進程accept客戶端連接蜘犁。當有新的連接到來時直接fork一個子進程翰苫,子進程中循環(huán)recv/send處理數(shù)據(jù)。這種模式在請求量不多的情況下很實用这橙,例如FTP服務(wù)器奏窑。

在過去多數(shù)Linux程序都時采用這種模式,簡單高效屈扎,代碼量少埃唯。當有幾百個并發(fā)的情況下表現(xiàn)不錯,但在大并發(fā)的情況下消耗就會過大。

例如:每個子進程都能創(chuàng)建一個與之對應(yīng)的文件,父進程也創(chuàng)建一個屬于自己的文件殃恒。

<?php
$socket = socket_create(AF_INET, SOCK_STREAM, 0);
if($socket < 0){
    $errmsg = socket_strerror($socket);
    echo "failed to create socket: {$errmsg}".PHP_EOL;
    exit;
}

$host = "0.0.0.0";
$port = 9601;
$ret = socket_bind($socket, $host, $port);
if($ret < 0){
    echo "failed to bind socket: {$ret}".PHP_EOL;
    exit;
}

$ret = socket_listen($socket, 0);
if($ret < 0){
    $errmsg = socket_strerror($ret);
    echo "failed to listen: {$errmsg}".PHP_EOL;
    exit;
}

while(pcntl_fork() == 0){
    $connection = @socket_accept($socket);
    if(pcntl_fork() == 0){
        $recv =  socket_read($connection ,8192);
        $data = "serverr: {$recv}";

        socket_write($connection ,$data);
        socket_close($connection);
        exit(0);
    }else{
        socket_close($connection);
    }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市漠趁,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌忍疾,老刑警劉巖闯传,帶你破解...
    沈念sama閱讀 212,383評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異膝昆,居然都是意外死亡丸边,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,522評論 3 385
  • 文/潘曉璐 我一進店門荚孵,熙熙樓的掌柜王于貴愁眉苦臉地迎上來妹窖,“玉大人,你說我怎么就攤上這事收叶〗竞簦” “怎么了?”我有些...
    開封第一講書人閱讀 157,852評論 0 348
  • 文/不壞的土叔 我叫張陵判没,是天一觀的道長蜓萄。 經(jīng)常有香客問我,道長澄峰,這世上最難降的妖魔是什么嫉沽? 我笑而不...
    開封第一講書人閱讀 56,621評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮俏竞,結(jié)果婚禮上绸硕,老公的妹妹穿的比我還像新娘堂竟。我一直安慰自己,他們只是感情好玻佩,可當我...
    茶點故事閱讀 65,741評論 6 386
  • 文/花漫 我一把揭開白布出嘹。 她就那樣靜靜地躺著,像睡著了一般咬崔。 火紅的嫁衣襯著肌膚如雪税稼。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,929評論 1 290
  • 那天垮斯,我揣著相機與錄音郎仆,去河邊找鬼。 笑死甚脉,一個胖子當著我的面吹牛丸升,可吹牛的內(nèi)容都是我干的铆农。 我是一名探鬼主播牺氨,決...
    沈念sama閱讀 39,076評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼墩剖!你這毒婦竟也來了猴凹?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,803評論 0 268
  • 序言:老撾萬榮一對情侶失蹤岭皂,失蹤者是張志新(化名)和其女友劉穎郊霎,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體爷绘,經(jīng)...
    沈念sama閱讀 44,265評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡书劝,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,582評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了土至。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片购对。...
    茶點故事閱讀 38,716評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖陶因,靈堂內(nèi)的尸體忽然破棺而出骡苞,到底是詐尸還是另有隱情,我是刑警寧澤楷扬,帶...
    沈念sama閱讀 34,395評論 4 333
  • 正文 年R本政府宣布解幽,位于F島的核電站,受9級特大地震影響烘苹,放射性物質(zhì)發(fā)生泄漏躲株。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 40,039評論 3 316
  • 文/蒙蒙 一镣衡、第九天 我趴在偏房一處隱蔽的房頂上張望霜定。 院中可真熱鬧吞琐,春花似錦、人聲如沸然爆。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,798評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽曾雕。三九已至奴烙,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間剖张,已是汗流浹背切诀。 一陣腳步聲響...
    開封第一講書人閱讀 32,027評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留搔弄,地道東北人幅虑。 一個月前我還...
    沈念sama閱讀 46,488評論 2 361
  • 正文 我出身青樓,卻偏偏與公主長得像顾犹,于是被迫代替她去往敵國和親倒庵。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,612評論 2 350

推薦閱讀更多精彩內(nèi)容

  • 要搞清楚fork的執(zhí)行過程炫刷,就必須先弄清楚操作系統(tǒng)中”進程(process)”的概念擎宝。 一個進程,主要包含三個元素...
    金星show閱讀 682評論 0 3
  • 1.內(nèi)存的頁面置換算法 (1)最佳置換算法(OPT)(理想置換算法):從主存中移出永遠不再需要的頁面极阅;如無這樣的...
    杰倫哎呦哎呦閱讀 3,237評論 1 9
  • Swift1> Swift和OC的區(qū)別1.1> Swift沒有地址/指針的概念1.2> 泛型1.3> 類型嚴謹 對...
    cosWriter閱讀 11,093評論 1 32
  • 所有知識點已整理成app app下載地址 J2EE 部分: 1.Switch能否用string做參數(shù)? 在 Jav...
    侯蛋蛋_閱讀 2,415評論 1 4
  • 必備的理論基礎(chǔ) 1.操作系統(tǒng)作用: 隱藏丑陋復(fù)雜的硬件接口涨享,提供良好的抽象接口筋搏。 管理調(diào)度進程,并將多個進程對硬件...
    drfung閱讀 3,530評論 0 5