2014-09-06 35 views
1

我正在開發一個網絡應用程序,我在端口上偵聽並在新的連接請求到達時創建一個新的套接字和線程;該架構運行良好,但我們正面臨嚴重的內存問題。PHP pthreads內存問題

問題是,即使我創建了一個單獨的線程,但它的工作,但內存不斷增加。

爲了演示這個問題,請查看下面的代碼,我們在其中啓動一個類的職責,它的職責是無限打印一個線程ID和一個隨機數。

class ThreadWorker extends Thread { 
    public function run() { 
     while(1) { 
      echo $this->getThreadId()." => ".rand(1,1000)."\r\n"; 
     } 
    } 
} 

$th = new ThreadWorker(); 
$th->start(); 

我開發它在Windows操作系統上,當我打開任務管理器的PHP.EXE內存使用量不斷增加,直到系統變得反應遲鈍。

請注意,PHP腳本是從命令行下執行:

PHP.exe pthreads-test.php 
+0

您是否在創建0和1線程的情況下測試了代碼? php.exe如何執行? (只是改變for循環的最高值) – Claudix 2014-09-06 10:15:30

+0

@Claudix如果我只是創建一個線程而不是100,那麼結果是完全相同的。讓我改變例子。 – 2014-09-06 10:17:49

+0

現在嘗試將線程的while(1)'循環(即刪除echo命令)留空。然後會發生什麼? – Claudix 2014-09-06 10:24:50

回答

1

OK,我認爲這個問題是該線程循環是非常佔用CPU。避免這樣的代碼。如果你只是想回應一條消息,我建議在之後放置一條sleep()指令。例如:

class ThreadWorker extends Thread { 
    public function run() { 
     while(1) { 
      echo $this->getThreadId()." => ".rand(1,1000)."\r\n"; 
      sleep(1); 
     } 
    } 
} 

編輯

看來there's a way強制垃圾收集在PHP。另一方面,sleep()不是穩定CPU使用的正確方法。通常,線程執行諸如從文件,套接字或管道讀取的操作,即它們通常執行通常爲阻塞的I/O操作(即,它們暫停線程,直到數據可以進行I/O操作爲止)。這種行爲固有地將CPU和其他資源交給其他線程,從而穩定整個系統。

+0

添加睡眠(1)穩定線程內存和處理器的使用情況,但我想在需要高延遲的網絡應用中休眠1秒會好嗎?有什麼辦法可以在線程內顯式調用PHP垃圾回收器嗎? – 2014-09-06 10:38:13

+0

不確定這是否可行。抱歉。 – Claudix 2014-09-06 16:38:34

+0

我發現了一種強制垃圾收集的方法:http://php.net/manual/en/function.gc-collect-cycles.php – Claudix 2014-09-07 11:26:31