當(dāng)提到PHP中的多線程時(shí),你可能認(rèn)為這是不可能的。然而,實(shí)際上我確實(shí)嘗試過這么做。
在接下來的內(nèi)容中,我將分享一些我已經(jīng)嘗試過的方法,它們完全可行。
我們都知道PHP本身不支持多線程,但我們的WEB服務(wù)器支持多線程。
也就是說,我們可以讓多個(gè)用戶同時(shí)訪問。這是我在PHP中實(shí)現(xiàn)多線程的基礎(chǔ)所在。
假設(shè)我們正在運(yùn)行一個(gè)名為a.php的文件。但在程序中,我又請(qǐng)求WEB服務(wù)器運(yùn)行另一個(gè)b.php。
這樣這兩個(gè)文件將同時(shí)執(zhí)行。
(PS: 一旦鏈接請(qǐng)求被發(fā)送,WEB服務(wù)器會(huì)立即執(zhí)行它,而不管客戶端是否已經(jīng)退出)
有時(shí)候,我們想要運(yùn)行的不是另一個(gè)文件,而是本文件中的某一部分代碼。要怎么辦呢?
實(shí)際上,我們可以通過參數(shù)控制a.php運(yùn)行哪一段程序。
示例
// a.php function runThread() { $fp = fsockopen('localhost', 80, $errno, $errmsg); fputs($fp, "GET /a.php?act=b\r\n\r\n"); // 這里的第二個(gè)參數(shù)是HTTP協(xié)議中規(guī)定的請(qǐng)求頭 // 不清楚的話請(qǐng)查看RFC中的定義 fclose($fp); } function a() { $fp = fopen('result_a.log', 'w'); fputs($fp, 'Set in ' . Date('h:i:s', time()) . (double)microtime() . "\r\n"); fclose($fp); } function b() { $fp = fopen('result_b.log', 'w'); fputs($fp, 'Set in ' . Date('h:i:s', time()) . (double)microtime() . "\r\n"); fclose($fp); } if (!isset($_GET['act'])) $_GET['act'] = 'a'; if ($_GET['act'] == 'a') { runThread(); a(); } else if ($_GET['act'] == 'b') b();
打開result_a.log和result_b.log,比較兩個(gè)文件中記錄的時(shí)間。你會(huì)發(fā)現(xiàn),這兩者確實(shí)是在不同的線程中運(yùn)行的,有時(shí)候甚至是完全相同的。
以上只是一個(gè)簡(jiǎn)單的例子,你可以根據(jù)需要進(jìn)行改進(jìn)。
既然PHP中也能實(shí)現(xiàn)多線程,那么問題也隨之而來,那就是同步問題。我們知道PHP本身不支持多線程,更不會(huì)有像Java中synchronize那樣的方法了。
那么我們?cè)撊绾翁幚砟兀?/h2>
1. 盡量避免訪問同一資源,以避免沖突。但是可以同時(shí)操作數(shù)據(jù)庫(kù),因?yàn)閿?shù)據(jù)庫(kù)支持并發(fā)操作。因此,在多線程的PHP中,不要向同一文件寫入數(shù)據(jù)。如果必須這樣做,使用其他方法進(jìn)行同步,例如調(diào)用`flock`對(duì)文件加鎖,或者創(chuàng)建臨時(shí)文件,并在另一個(gè)線程中等待該文件消失,類似于`while(file_exists('xxx'));`這樣的做法。這表示當(dāng)臨時(shí)文件存在時(shí),表示另一個(gè)線程正在操作,而當(dāng)文件消失時(shí),表示其他線程已經(jīng)釋放了該資源。
2. 盡量避免在執(zhí)行`fputs`后從`runThread`中的套接字讀取數(shù)據(jù)。因?yàn)橐獙?shí)現(xiàn)多線程,需要使用非阻塞模式。也就是說,在像`fgets`這樣的函數(shù)中立即返回。因此,在讀寫數(shù)據(jù)時(shí)可能會(huì)出現(xiàn)問題。如果使用阻塞模式,程序就不能算是多線程了。它將等待上面的返回后才執(zhí)行下面的程序。所以,如果需要交換數(shù)據(jù),最好利用外部文件或數(shù)據(jù)來完成。如果一定要這么做,可以使用`socket_set_nonblock($fp)`來實(shí)現(xiàn)。
那么,這種做法是否有實(shí)際意義呢?在什么情況下需要使用這種方法呢?
答案肯定是肯定的。眾所周知,在一個(gè)持續(xù)讀取網(wǎng)絡(luò)資源的應(yīng)用中,網(wǎng)絡(luò)速度往往是瓶頸。如果采用多線程的形式,就可以同時(shí)對(duì)不同頁面進(jìn)行讀取。
我開發(fā)過一個(gè)程序,可以從類似8848和soaso這樣的商城網(wǎng)站搜索信息。還有另一個(gè)程序從阿里巴巴網(wǎng)站獲取商業(yè)信息和公司目錄,也用到了這種技術(shù)。因?yàn)檫@兩個(gè)程序都需要不斷連接到它們的服務(wù)器讀取信息并保存到數(shù)據(jù)庫(kù)。利用這項(xiàng)技術(shù)恰好消除了等待響應(yīng)時(shí)的瓶頸。文章來源:http://www.zghlxwxcb.cn/article/719.html
希望本文能夠幫助你更好地理解在PHP中實(shí)現(xiàn)多線程的方法以及如何應(yīng)用于實(shí)際場(chǎng)景中。如果您有任何問題或想要進(jìn)一步探討,請(qǐng)隨時(shí)提出。文章來源地址http://www.zghlxwxcb.cn/article/719.html
到此這篇關(guān)于深入探討PHP中的多線程實(shí)現(xiàn)方法的文章就介紹到這了,更多相關(guān)內(nèi)容可以在右上角搜索或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!