我使用 popen 和 fgets 异步读取 tcpdump 的输出。
下面的代码应该在命令行中运行,而不是使用 apache 并在浏览器中查看它。
$handle = popen('tcpdump -nnX', 'r');
while (true) {
$output = fgets($handle);
print $output . "\n";
}
当我尝试通过 websockets 输出此信息时,问题就出现了。
Websockets 还使用无限循环(用于管理其套接字、滴答声和消息)。
它看起来像:
while (true) {
@socket_select($read,$write,$except,1);
foreach ($read as $socket) {
if ($socket == $this->master) {
$client = socket_accept($socket);
...
我使用 $websocket->sendToAll($message); 通过 websocket 发送数据。
在这种情况下我能做什么?我对线程、分叉脚本之间的通信或其他任何东西的想法持开放态度。
这是经典场景Producer-Consumer
问题。只是你有两个而已。您可以分解问题以更容易理解。
WebSocket 消费者:此代码将通过WebSocket发送数据。您可以将其视为一个单独的线程,其中数据从队列中出列Q1
(只是一个名字)并发送。
WebSocket 生产者:一旦一些数据到达 WebSocket 门,它就会被排队到缓冲区中。只是这和上面的队列不一样。让我们命名它Q2
。这也需要是一个单独的线程,一旦该线程将数据排队并向适当的消费者发出信号,该线程就会进入睡眠状态。
硬盘消费类:此代码将执行与 WebSocket Consumer 相同的操作,唯一的区别是它将数据存储在硬盘上而不是 WebSocket 上。它将有自己的线程并与Q2
.
硬盘生产商: 我相信你能猜到这是做什么的。此代码将从硬盘读取数据并将其放入Q1
队列。与所有生产者一样,它需要向消费者发出信号,通知他们队列中有新项目。
现在回到你的代码,PHP 不适合多线程编程,尽管这是完全可能的 http://php.net/manual/en/intro.pthreads.php。这就是为什么你找不到那么多例子的原因。但如果您坚持的话,您需要以下内容:
PHP 的 Thread 类 http://php.net/manual/en/class.thread.php
PHP 的 Mutex 类 http://php.net/manual/en/class.mutex.php。此类将帮助您防止多个线程同时访问相同的数据。
有事打电话Signaling
我在 PHP 中找不到!它被用来
告诉其他线程队列中的某些数据已准备好
Consumer,或者说,会唤醒消费者线程
当它有事情要做的时候。
最后一句话是,在适当的多线程软件中,您不会使用sleep
降低系统负载/防止系统崩溃的功能。多线程编程就是线程之间的信号传递和对话。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)