2014-09-06 67 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