閑言之PHP不支持多線程??

前言

為什么考慮到多線程呢?--------為了有效率的解決并發(fā)問題;

那怎么將多線程應(yīng)用結(jié)合到PHP應(yīng)用解決并發(fā)問題的過程中呢?

--------那就要回想一下“HTTP請求響應(yīng)過程了”,對PHP而言,一個典型的HTTP事務(wù):客戶端構(gòu)造請求——》http守護進程監(jiān)聽到請求,php-fpm【針對php的fast-cgi】從在初始化時就啟動的多個cgi解釋器子進程中選擇并連接到其中一個;此“幸運兒”解釋器子進程負責處理請求,比如IO訪問啦,數(shù)據(jù)庫記錄增刪改查啦等等——》cgi解釋子進程完成處理后將標準輸出和錯誤信息從同一連接返回Web Server,Web Server將處理結(jié)果構(gòu)造成響應(yīng)體返送給客戶端。

來,我們看看如上的發(fā)生過程,看看PHP代碼層我們能做些什么?

事務(wù)的第一步:客戶端并發(fā)訪問,這只是問題的根源;第二步:服務(wù)器端的http守護進程監(jiān)聽請求,并從多進程模型的php-fpm選擇子解釋器進程處理請求,比如nginx服務(wù)器是要通過負載均衡,調(diào)整各種配置(nginx.conf, php-fpm.ini, php.ini)、這顯然跟我們代碼層也沒什么關(guān)系;唯一可能有關(guān)系的地方就是子進程解釋器解釋代碼邏輯的時候了,然而php-fpm是多進程單線程模型,被選中的Only One fast-cgi解釋器子進程負責解釋PHP代碼邏輯,或者我們可以在“ Only One“的fast-cgi進程下搞些多線程做文章??;第三部Web Server將處理結(jié)果封裝響應(yīng)體,顯然代碼層在此也只能“望洋興嘆”了;

另一方面來講,進程、線程本來就是底層操作系統(tǒng)的實現(xiàn),比如常用于多線程的JAVA,它的解析過程【非解釋過程】是跑在JVM上的,在設(shè)計之初就考慮到了多線程,它的“線程”實際上是一種封裝抽象出來的概念,而PHP誰讓它是靠解釋器解釋而非編譯解析的呢?。

PHP多線程/多進程技術(shù)現(xiàn)狀

1. curl_multi多線程請求URL

curl多用于跨域請求訪問,當需要請求多個URL時,相較于for循環(huán)的curl_exec,我們可以使用curl_multi一類函數(shù)實現(xiàn)同時請求多個URL,類似多線程功能,據(jù)文檔介紹:“Allows the processing of multiple cURL handles asynchronously(異步). ? ? ? ? tips: curl_multi_select—Wait for activity on any curl_multi connection。Blocks until there is activity on any of the curl_multi connections.

使用范例可參見:http://www.cnblogs.com/chunguang/p/5895160.html

代碼實例片段如下:

2. pcntl_fork創(chuàng)建子進程

據(jù)文檔介紹:pcntl_fork()function creates a child process that differs from the parent process only in its PID and PPID. 另當其被用于Web服務(wù)環(huán)境時可能會帶來意外的結(jié)果。

至于上文提到的被用于Web服務(wù)環(huán)境時可能會帶來意外的結(jié)果,插播一則“廣告”,首先介紹下什么是“僵尸進程”。

進程調(diào)用exit之后,其并非馬上就消失掉,而是留下一個稱為“僵尸進程”(Zombie)的數(shù)據(jù)結(jié)構(gòu)。在Linux進程的5種狀態(tài)【運行,中斷,不可中斷(收到信號不喚醒和不可運行, 進程必須等待直到有中斷發(fā)生),停止,僵死】中,僵尸進程是非常特殊的一種,它已經(jīng)放棄了幾乎所 有內(nèi)存空間,沒有任何可執(zhí)行代碼,也不能被調(diào)度,僅僅在進程列表中保留一個位置,記載該進程的退出狀態(tài)等信息供其他進程收集。

所以,進程退出后,系統(tǒng)會把該進程的狀態(tài)變成Zombie,然后給上一定的時間等著父進程來收集其退出信息,因為可能父進程正忙于別的事情來不及收集,所以,使用Zombie狀態(tài)表示進程退出了,正在等待父進程收集信息中。如果需要清除這樣的進程,那么需要清除其父進程,或是等很長的時間后被內(nèi)核清除。因為 Zombie的進程還占著個進程ID號呢,這樣的進程如果很多的話,不利于系統(tǒng)的進程調(diào)度。

pcntl中多進程并發(fā)控制的用例可參見:http://blog.csdn.net/lgg201/article/details/5996444。

接著說上面的意外結(jié)果,手冊上有這么一段話:

Process Control support in PHP implements the Unix style of process creation, program execution, signal handling and process termination. Process Control should not be enabled within a web server environment and unexpected results may happen if any Process Control functions are used within a web server environment.

比如,曾經(jīng)有人嘗試過采用php提供的pcntl_fork + 管道的方式實現(xiàn)并行數(shù)據(jù)拉取與同步【http://www.cnblogs.com/bourneli/archive/2012/07/06/2579804.html】,據(jù)說標準輸出(瀏覽器)全都給到fork出的子進程,導(dǎo)致主進程無任何輸出,瀏覽器無法接收來自主進程的數(shù)據(jù)?

個人猜想:既然子進程和父進程的執(zhí)行依賴于操作系統(tǒng)調(diào)度,完全可以依賴進程間通信或者維護個父子進程關(guān)系表結(jié)構(gòu)啊,如果并行拉取的數(shù)據(jù)沒有限定次序關(guān)系的話,直接將輸出送到主進程,主進程判斷是否還有其他子進程未將輸出結(jié)果送回,而決定是否echo直接結(jié)束腳本,當然如果有次序要求,在子進程創(chuàng)建時記錄附加標志信息就可以重排序了呀。

3. multi-threading pthreads擴展

pecl擴展,安裝需要ZTS aka thread safety (線程安全模式),且只能用在CLI命令行環(huán)境下,不能在web server 環(huán)境下使用。

使用實例和范例可參見:

http://blog.csdn.net/gavin_new/article/details/65444190

http://masnun.com/2013/12/15/multithreading-in-php-doing-it-right.html

https://www.sitepoint.com/parallel-programming-pthreads-php-fundamentals/

4. swoole_client的異步模式

swoole開源項目實際上是一個網(wǎng)絡(luò)通信和異步io的引擎,一個基礎(chǔ)庫。swoole一般也是基于cli下的腳本編程。

http://rango.swoole.com/8

https://pecl.php.net/package/swoole

代碼示例:

5. yield socket_create

以同步方式書寫的異步代碼示例:

http://www.jb51.net/article/81245.htm

https://www.mullie.eu/parallel-processing-multi-tasking-php/

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 轉(zhuǎn)載自:http://www.cnblogs.com/txw1958/archive/2013/01/19/286...
    php_bruce閱讀 2,449評論 1 5
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,506評論 19 139
  • cURL是一個利用URL語法規(guī)定來傳輸文件和數(shù)據(jù)的工具,支持很多協(xié)議和選項,如HTTP、FTP、TELNET等,能...
    司馬東陽閱讀 1,515評論 0 6
  • 他朝火焰走去?;鹧鏇]有吞噬他的皮肉,而是不燙不灼地撫慰他,淹沒了他。他寬慰地、慚愧地、害怕地知道他自己也是一個幻影...
    李澤賢閱讀 965評論 0 3
  • 敬重山 一座座或高或低的山們,經(jīng)過數(shù)以萬年的風雨剝蝕后,仍然以偉大的山的形態(tài),保持著骨俊神...
    徐山燕老閱讀 589評論 0 1

友情鏈接更多精彩內(nèi)容