中文字幕免费精品_亚洲视频自拍_亚洲综合国产激情另类一区_色综合咪咪久久

PHP多進(jìn)程編程實(shí)例
來源:易賢網(wǎng) 閱讀:1734 次 日期:2014-10-17 14:05:23
溫馨提示:易賢網(wǎng)小編為您整理了“PHP多進(jìn)程編程實(shí)例”,方便廣大網(wǎng)友查閱!

羨慕火影忍者里鳴人的影分身么?沒錯(cuò),PHP程序是可以開動(dòng)影分身的!想完成任務(wù),又覺得一個(gè)進(jìn)程太慢,那么,試試用多進(jìn)程來搞吧。這篇文章將會(huì)介紹一下PHP多進(jìn)程的基本需求,如何創(chuàng)建多進(jìn)程以及基本的信號(hào)控制,暫時(shí)不會(huì)告訴你如何進(jìn)行進(jìn)程間通信和信息共享。

1. 準(zhǔn)備

在動(dòng)手之前,請確定你用的不是M$ Windows平臺(tái)(因?yàn)槲覜]有Windows)。Linux / BSD / Unix應(yīng)該都是沒問題的。確認(rèn)好了工作環(huán)境以后一起來看看我們需要的PHP模塊是否都有。打開終端輸入下面的命令:

代碼如下:

$ php -m

這個(gè)命令檢查并打印當(dāng)前PHP所有開啟的擴(kuò)展,看一下pcntl和posix是否在輸出的列表中。

1.1. pcntl

如果找不到pcntl,八成是編譯的時(shí)候沒把這個(gè)擴(kuò)展編譯進(jìn)去。如果你和我一樣是編譯安裝的PHP,那么需要重新編譯安裝PHP。在配置的時(shí)候記得加上--enable-pcntl參數(shù)即可。

代碼如下:

$ cd /path/to/php_source_code_dir

$ ./configure [some other options] --enable-pcntl

$ make && make install

1.2. posix

這貨一般默認(rèn)就會(huì)裝上,只要你編譯的時(shí)候沒有加上--disable-posix。

2. 預(yù)備知識(shí)

在繼續(xù)之前,你還需要對Linux多進(jìn)程有一點(diǎn)了解。多進(jìn)程是咋回事呢?這里可跟火影忍者里的影分身稍微有點(diǎn)不同。首先,鳴人從小長到大,比如16歲,咳。有一天他發(fā)動(dòng)了影分身,分出了5個(gè)他。顯然,這些分身也是16歲的鳴人而不是剛出生啥也不懂就會(huì)哭的嬰兒(那叫克隆)。然后,不一樣的地方來了:分身們變成了獨(dú)立的人各自去做各自的事,互相之間不再知道其他分身和原身都做了什么(當(dāng)然不會(huì)像動(dòng)畫片里一樣積累經(jīng)驗(yàn)給原身啦)。除非,他們互相之間有交流,不然,只有16歲之前的事情才是他們共同的記憶。

有同學(xué)說了,老大你這不坑爹呢么?我又沒看過火影忍者!那你去看一遍好了……

最后,預(yù)備知識(shí)完了,就是大致了解一下主進(jìn)程開出來的子進(jìn)程是怎么回事。子進(jìn)程的代碼和主進(jìn)程是完全一樣的,還有一部分一樣的東西就是直到發(fā)動(dòng)影分身之前執(zhí)行的所有內(nèi)容。

3. 影分身之術(shù)

所以呢,沒有點(diǎn)基礎(chǔ)知識(shí)怎么能理解卷軸里的內(nèi)容呢?打開卷軸首先看到了一個(gè)單詞:fork。

3.1. fork

叉子?叉子是分岔的,一個(gè)變多個(gè)嘛!差不多就是這個(gè)意思。創(chuàng)建子進(jìn)程就用這個(gè)命令。這里需要用到pcntl_fork()函數(shù)。(可以先簡單看一下PHP手冊關(guān)于這個(gè)函數(shù)的介紹。)創(chuàng)建一個(gè)PHP腳本:

代碼如下:

$pid = pcntl_fork(); // 一旦調(diào)用成功,事情就變得有些不同了

if ($pid == -1) {

die('fork failed');

} else if ($pid == 0) {

} else {

}

pcntl_fork()函數(shù)創(chuàng)建一個(gè)子進(jìn)程,子進(jìn)程和父進(jìn)程唯一的區(qū)別就是PID(進(jìn)程ID)和PPID(父進(jìn)程ID)不同。在終端下查看進(jìn)程用ps命令(問問man看ps怎么用:man ps)。當(dāng)函數(shù)返回值為-1的時(shí)候,說明fork失敗了。試試在if前面加一句:echo $pid . PHP_EOL;。運(yùn)行你的腳本,輸出可能像下面這樣(結(jié)果說明子進(jìn)程和父進(jìn)程的代碼是相同的):

代碼如下:

67789 # 這個(gè)是父進(jìn)程打印的

0 # 這個(gè)是子進(jìn)程打印的

pcntl_fork()函數(shù)調(diào)用成功后,在父進(jìn)程中會(huì)返回子進(jìn)程的PID,而在子進(jìn)程中返回的是0。所以,下面直接用if分支來控制父進(jìn)程和子進(jìn)程做不同的事。

3.2. 分配任務(wù)

然后我們來說說鳴人16歲那次影分身的事兒,給原身和分身分配兩個(gè)簡單的輸出任務(wù):

代碼如下:

$parentPid = getmypid(); // 這就是傳說中16歲之前的記憶

$pid = pcntl_fork(); // 一旦調(diào)用成功,事情就變得有些不同了

if ($pid == -1) {

die('fork failed');

} else if ($pid == 0) {

$mypid = getmypid(); // 用getmypid()函數(shù)獲取當(dāng)前進(jìn)程的PID

echo 'I am child process. My PID is ' . $mypid . ' and my father's PID is ' . $parentPid . PHP_EOL;

} else {

echo 'Oh my god! I am a father now! My child's PID is ' . $pid . ' and mine is ' . $parentPid . PHP_EOL;

}

輸出的結(jié)果可能是這樣:

代碼如下:

Oh my god! I am a father now! My child's PID is 68066 and mine is 68065

I am child process. My PID is 68066 and my father's PID is 68065

再強(qiáng)調(diào)一下,pcntl_fork()調(diào)用成功以后,一個(gè)程序變成了兩個(gè)程序:一個(gè)程序得到的$pid變量值是0,它是子進(jìn)程;另一個(gè)程序得到的$pid的值大于0,這個(gè)值是子進(jìn)程的PID,它是父進(jìn)程。在下面的分支語句中,由于$pid值的不同,運(yùn)行了不同的代碼。再次強(qiáng)調(diào)一下:子進(jìn)程的代碼和父進(jìn)程的是一樣的。所以就要通過分支語句給他們分配不同的任務(wù)。

3.3. 子進(jìn)程回收

剛剛有man ps么?一般我習(xí)慣用ps aux加上grep命令來查找運(yùn)行著的后臺(tái)進(jìn)程。其中有一列STAT,標(biāo)識(shí)了每個(gè)進(jìn)程的運(yùn)行狀態(tài)。這里,我們關(guān)注狀態(tài)Z:僵尸(Zombie)。當(dāng)子進(jìn)程比父進(jìn)程先退出,而父進(jìn)程沒對其做任何處理的時(shí)候,子進(jìn)程將會(huì)變成僵尸進(jìn)程。Oops,又跟火影里的影分身不一樣了。鳴人的影分身被干死了以后就自動(dòng)消失了,但是這里的子進(jìn)程分身死了話還留著一個(gè)空殼在,直到父進(jìn)程回收它。僵尸進(jìn)程雖然不占什么內(nèi)存,但是很礙眼,院子里一堆躺著的僵尸怎么都覺得怪怪的。(別忘了它們還占用著PID)

一般來說,在父進(jìn)程結(jié)束之前回收掛掉的子進(jìn)程就可以了。在pcntl擴(kuò)展里面有一個(gè)pcntl_wait()函數(shù),它會(huì)將父進(jìn)程掛起,直到有一個(gè)子進(jìn)程退出為止。如果有一個(gè)子進(jìn)程變成了僵尸的話,它會(huì)立即返回。所有的子進(jìn)程都要回收,所以多等等也沒關(guān)系啦!

3.4. 父進(jìn)程先掛了

如果父進(jìn)程先掛了怎么辦?會(huì)發(fā)生什么?什么也不會(huì)發(fā)生,子進(jìn)程依舊還在運(yùn)行。但是這個(gè)時(shí)候,子進(jìn)程會(huì)被交給1號(hào)進(jìn)程,1號(hào)進(jìn)程成為了這些子進(jìn)程的繼父。1號(hào)進(jìn)程會(huì)很好地處理這些進(jìn)程的資源,當(dāng)它們結(jié)束時(shí)1號(hào)進(jìn)程會(huì)自動(dòng)回收資源。所以,另一種處理僵尸進(jìn)程的臨時(shí)辦法是關(guān)閉它們的父進(jìn)程。

4. 信號(hào)

一般多進(jìn)程的事兒講到上面就完了,可是信號(hào)在系統(tǒng)中確實(shí)是一個(gè)非常重要的東西。信號(hào)就是信號(hào)燈,點(diǎn)亮一個(gè)信號(hào)燈,程序就會(huì)做出反應(yīng)。這個(gè)你一定用過,比如說在終端下運(yùn)行某個(gè)程序,等了半天也沒什么反應(yīng),可能你會(huì)按 Ctrl+C 來關(guān)閉這個(gè)程序。實(shí)際上,這里就是通過鍵盤向程序發(fā)送了一個(gè)中斷的信號(hào):SIGINT。有時(shí)候進(jìn)程失去響應(yīng)了還會(huì)執(zhí)行kill [PID]命令,未加任何其他參數(shù)的話,程序會(huì)接收到一個(gè)SIGTERM信號(hào)。程序收到上面兩個(gè)信號(hào)的時(shí)候,默認(rèn)都會(huì)結(jié)束執(zhí)行,那么是否有可能改變這種默認(rèn)行為呢?必須能啊!

4.1. 注冊信號(hào)

人是活的程序也是活的,只不過程序需要遵循人制定的規(guī)則來運(yùn)行。現(xiàn)在開始給信號(hào)重新設(shè)定規(guī)則,這里用到的函數(shù)是pcntl_signal()(繼續(xù)之前為啥不先查查PHP手冊呢?)。下面這段程序?qū)⒔oSIGINT重新定義行為,注意看好:

代碼如下:

// 定義一個(gè)處理器,接收到SIGINT信號(hào)后只輸出一行信息

function signalHandler($signal) {

if ($signal == SIGINT) {

echo 'signal received' . PHP_EOL;

}

}

// 信號(hào)注冊:當(dāng)接收到SIGINT信號(hào)時(shí),調(diào)用signalHandler()函數(shù)

pcntl_signal(SIGINT, 'signalHandler');

while (true) {

sleep(1);

// do something

pcntl_signal_dispatch(); // 接收到信號(hào)時(shí),調(diào)用注冊的signalHandler()

}

執(zhí)行一下,隨時(shí)按下 Ctrl+C 看看會(huì)發(fā)生什么事。

4.2. 信號(hào)分發(fā)

說明一下:pcntl_signal()函數(shù)僅僅是注冊信號(hào)和它的處理方法,真正接收到信號(hào)并調(diào)用其處理方法的是pcntl_signal_dispatch()函數(shù)。試試把// do something替換成下面這段代碼:

代碼如下:

for ($i = 0; $i < 1000000; $i++) {

echo $i . PHP_EOL;

usleep(100000);

}

在終端下執(zhí)行這個(gè)腳本,當(dāng)它不停輸出數(shù)字的時(shí)候嘗試按下 Ctrl+C 。看看程序有什么響應(yīng)?嗯……什么都沒有,除了屏幕可能多了個(gè)^C以外,程序一直在不停地輸出數(shù)字。因?yàn)槌绦蛞恢睕]有執(zhí)行到pcntl_signal_dispatch(),所以就并沒有調(diào)用signalHandler(),所以就沒有輸出signal received。

4.3. 版本問題

如果認(rèn)真看了PHP文檔,會(huì)發(fā)現(xiàn)pcntl_signal_dispatch()這個(gè)函數(shù)是PHP 5.3以上才支持的,如果你的PHP版本大于5.3,建議使用這個(gè)方法調(diào)用信號(hào)處理器。5.3以下的版本需要在注冊信號(hào)之前加一句:declare(ticks = 1);表示每執(zhí)行一條低級(jí)指令,就檢查一次信號(hào),如果檢測到注冊的信號(hào),就調(diào)用其信號(hào)處理器。想想就挺不爽的,干嘛一直都檢查?還是在我們指定的地方檢查一下就好。

4.4. 感受僵尸進(jìn)程

現(xiàn)在我們回到子進(jìn)程回收的問題上(差點(diǎn)忘了= =")。當(dāng)你的一個(gè)子進(jìn)程掛了(或者說是結(jié)束了),但是父進(jìn)程還在運(yùn)行中并且可能很長一段時(shí)間不會(huì)退出。一個(gè)僵尸進(jìn)程從此站起來了!這時(shí),保護(hù)傘公司(內(nèi)核)發(fā)現(xiàn)它的地盤里出現(xiàn)了一個(gè)僵尸,這個(gè)僵尸是誰兒子呢?看一下PPID就知道了。然后,內(nèi)核給PPID這個(gè)進(jìn)程(也就是僵尸進(jìn)程的父進(jìn)程)發(fā)送一個(gè)信號(hào):SIGCHLD。然后,你知道怎么在父進(jìn)程中回收這個(gè)子進(jìn)程了么?提示一下,用pcntl_wait()函數(shù)。

4.5. 發(fā)送信號(hào)

希望剛剛有認(rèn)真man過kill命令。它其實(shí)就是向進(jìn)程發(fā)送信號(hào),在PHP中也可以調(diào)用posix_kill()函數(shù)來達(dá)到相同的效果。有了它就可以在父進(jìn)程中控制其他子進(jìn)程的運(yùn)行了。比如在父進(jìn)程結(jié)束之前關(guān)閉所有子進(jìn)程,那么fork的時(shí)候在父進(jìn)程記錄所有子進(jìn)程的PID,父進(jìn)程結(jié)束之前依次給子進(jìn)程發(fā)送結(jié)束信號(hào)即可。

5. 實(shí)踐

PHP的多進(jìn)程跟C還是挺像的,搞明白了以后用其他語言寫的話也大同小異差不多都是這么個(gè)情況。如果有空的話,嘗試寫一個(gè)小程序,切身體會(huì)一下個(gè)中滋味:

1.16歲的鳴人發(fā)送影分身,分出5個(gè)分身

2.每個(gè)分身隨機(jī)生存10到30秒,每秒都輸出點(diǎn)什么

3.保證原身能感受到分身的結(jié)束,然后開動(dòng)另一個(gè)分身,保證最多有5個(gè)分身

4.不使用nohup,讓原身在終端關(guān)閉后依舊能夠運(yùn)行

5.把分身數(shù)量(5)寫進(jìn)一個(gè)配置文件里,當(dāng)給原身發(fā)送信號(hào)(可以考慮用SIGUSR1或SIGUSR2)時(shí),原身讀取配置文件并更新允許的分身最大數(shù)量

6.如果分身多了,關(guān)閉幾個(gè);如果少了,再分出來幾個(gè)

提示:

1.用while循環(huán)保證進(jìn)程運(yùn)行,注意sleep以免100%的CPU占用

2.運(yùn)行進(jìn)程的終端被關(guān)閉時(shí),程序會(huì)收到一個(gè)SIGHUP信號(hào)

3.可以用parse_ini_file()函數(shù)解析INI配置文件

更多信息請查看IT技術(shù)專欄

更多信息請查看腳本欄目
易賢網(wǎng)手機(jī)網(wǎng)站地址:PHP多進(jìn)程編程實(shí)例
由于各方面情況的不斷調(diào)整與變化,易賢網(wǎng)提供的所有考試信息和咨詢回復(fù)僅供參考,敬請考生以權(quán)威部門公布的正式信息和咨詢?yōu)闇?zhǔn)!

2026上岸·考公考編培訓(xùn)報(bào)班

  • 報(bào)班類型
  • 姓名
  • 手機(jī)號(hào)
  • 驗(yàn)證碼
關(guān)于我們 | 聯(lián)系我們 | 人才招聘 | 網(wǎng)站聲明 | 網(wǎng)站幫助 | 非正式的簡要咨詢 | 簡要咨詢須知 | 新媒體/短視頻平臺(tái) | 手機(jī)站點(diǎn) | 投訴建議
工業(yè)和信息化部備案號(hào):滇ICP備2023014141號(hào)-1 云南省教育廳備案號(hào):云教ICP備0901021 滇公網(wǎng)安備53010202001879號(hào) 人力資源服務(wù)許可證:(云)人服證字(2023)第0102001523號(hào)
云南網(wǎng)警備案專用圖標(biāo)
聯(lián)系電話:0871-65099533/13759567129 獲取招聘考試信息及咨詢關(guān)注公眾號(hào):hfpxwx
咨詢QQ:1093837350(9:00—18:00)版權(quán)所有:易賢網(wǎng)
云南網(wǎng)警報(bào)警專用圖標(biāo)
中文字幕免费精品_亚洲视频自拍_亚洲综合国产激情另类一区_色综合咪咪久久
欧美成人午夜激情| 永久555www成人免费| 亚洲国产精品黑人久久久| 国产精品mm| 欧美精品色网| 免费国产自线拍一欧美视频| 欧美一区二区三区日韩视频| 亚洲一区在线免费观看| 亚洲视频自拍偷拍| 亚洲永久精品国产| 亚洲免费网站| 性色一区二区三区| 亚洲欧美在线观看| 欧美一区激情视频在线观看| 亚洲欧美日产图| 欧美一区二粉嫩精品国产一线天| 一本一本久久a久久精品牛牛影视| 亚洲高清资源| 亚洲日本无吗高清不卡| 亚洲日本va午夜在线电影| 亚洲精品资源| 亚洲天堂成人在线观看| 亚洲小少妇裸体bbw| 亚洲欧美日韩一区| 欧美在线看片| 麻豆9191精品国产| 欧美日韩99| 国产精品爽爽爽| 黄色成人91| 亚洲精品久久久久久久久久久久久| 亚洲三级网站| 亚洲欧美另类国产| 久久视频在线看| 欧美日韩国内自拍| 国产欧美不卡| 91久久精品久久国产性色也91| 亚洲黄色高清| 亚洲一区二区精品在线观看| 久久国产精品99久久久久久老狼| 久久久夜夜夜| 欧美性猛交xxxx乱大交蜜桃| 狠狠v欧美v日韩v亚洲ⅴ| 亚洲日本中文字幕免费在线不卡| 亚洲手机在线| 久久综合精品国产一区二区三区| 欧美电影免费| 国产精品视频导航| 亚洲国产精品一区制服丝袜 | 欧美三级网页| 国产亚洲激情在线| 亚洲精品乱码久久久久久| 亚洲夜晚福利在线观看| 久久久国产精品一区二区中文| 免费观看成人www动漫视频| 欧美日韩妖精视频| 在线观看亚洲视频| 亚洲视频欧美视频| 久久婷婷人人澡人人喊人人爽| 欧美日韩大片| 影音先锋久久| 亚洲永久网站| 欧美精品日韩| 今天的高清视频免费播放成人 | 亚洲精品国产精品乱码不99按摩| 亚洲淫性视频| 欧美日韩色综合| 亚洲福利视频免费观看| 香蕉成人啪国产精品视频综合网| 欧美1区免费| 国产综合av| 午夜精品久久久久久99热软件 | 亚洲电影中文字幕| 欧美一级久久久| 亚洲欧美中文日韩v在线观看| 欧美精品 国产精品| 黄色成人av在线| 久久精品视频播放| 国产精品女主播在线观看| 亚洲精品三级| 久久久一本精品99久久精品66| 国产精品视频久久久| 99精品黄色片免费大全| 麻豆av一区二区三区久久| 国产在线日韩| 久久久久免费视频| 国产一区在线看| 亚洲欧美春色| 国产精品美女久久久久久免费| 一区二区三区欧美在线| 欧美日韩国产一级| 一本大道久久a久久综合婷婷| 欧美久久久久久久| 一本久道久久综合狠狠爱| 欧美激情精品久久久久久大尺度| 亚洲第一区中文99精品| 久久另类ts人妖一区二区| 亚洲第一综合天堂另类专| 久久深夜福利| 亚洲福利视频二区| 欧美国产日产韩国视频| 亚洲三级视频| 欧美日韩三区| 亚洲欧美日韩另类精品一区二区三区| 欧美日韩一区二区三区在线看| 亚洲天堂av在线免费| 国产精品夜夜夜| 欧美影院成人| 在线精品国产成人综合| 欧美freesex交免费视频| 亚洲肉体裸体xxxx137| 欧美经典一区二区三区| 一区二区激情小说| 国产精品青草综合久久久久99 | 最新精品在线| 欧美日韩小视频| 亚洲线精品一区二区三区八戒| 国产精品国产福利国产秒拍| 香蕉成人久久| 好吊视频一区二区三区四区| 美女国内精品自产拍在线播放| 在线观看av不卡| 欧美日韩国产不卡| 亚洲综合色婷婷| 国内精品久久久久久久影视麻豆| 久久五月天婷婷| 亚洲精品一线二线三线无人区| 欧美日韩国产欧美日美国产精品| 一区二区三区视频在线观看| 国产欧美精品日韩精品| 久久久五月天| 亚洲精品乱码久久久久久黑人| 欧美日本不卡| 欧美一区二区三区在线看| 亚洲第一在线综合网站| 欧美日韩精品免费观看| 久久黄金**| 一本色道久久综合狠狠躁的推荐| 国产女主播一区二区| 欧美成人在线免费视频| 亚洲一区免费网站| 亚洲黄网站在线观看| 国产日韩成人精品| 欧美理论电影在线播放| 久久成人免费电影| 一区二区日本视频| 在线看国产日韩| 国产精品一页| 欧美国产高清| 久久婷婷亚洲| 亚洲欧洲99久久| 一本色道久久综合亚洲二区三区 | 精品不卡视频| 国产精品v日韩精品| 免费看av成人| 久久久福利视频| 国产伦精品一区二区三区免费 | 久久亚洲国产成人| 亚洲一区二区三区久久| 亚洲东热激情| 国产一区二区成人久久免费影院| 欧美日韩国产色综合一二三四| 久久三级福利| 欧美中文字幕视频| 亚洲欧美电影在线观看| 亚洲深夜福利视频| 日韩网站在线看片你懂的| 激情综合电影网| 国产欧美一区二区三区在线看蜜臀| 欧美日本不卡高清| 你懂的视频一区二区| 久久久久久亚洲精品中文字幕| 亚洲专区在线| 亚洲一区二区三区免费视频| 亚洲美女在线看| 亚洲九九精品| 亚洲精品欧洲| 亚洲国产小视频在线观看| 狠狠色综合网站久久久久久久| 国产噜噜噜噜噜久久久久久久久| 欧美手机在线| 国产精品久久久久久久久久妞妞 | 性色av一区二区三区| 亚洲深夜福利网站| 亚洲一区二区三区777| 亚洲午夜国产成人av电影男同| 亚洲精品永久免费精品| 国产亚洲欧美色| 国产一区二区高清| 国户精品久久久久久久久久久不卡| 国产日韩精品在线观看| 国产一区av在线| 在线电影国产精品| 91久久国产综合久久| 亚洲人精品午夜| 夜夜嗨av色综合久久久综合网| 日韩午夜黄色| 亚洲一区精彩视频| 久久成年人视频| 久久中文字幕一区| 欧美精品日本|