php forking子进程执行无限循环

时间:2014-04-28 18:36:39

标签: php process fork

我对php比较陌生,但我可以用其他语言编程(js,java,c / c ++)。我有一个问题,我似乎无法解决,所以我希望有人可以帮助我在这里:)

我创建了一个server_class.php文件,用于管理多个客户端之间的连接。客户端通过Web连接到php服务器。当我启动server_class.php时,它执行两个应用程序(它们处于无限循环中)并将数据打印到终端。当客户端连接到php服务器时,我希望服务器开始将每个应用程序的输出发送到每个客户端,这样客户端就可以看到每个应用程序的当前输出。我已经部分实现了这一点。但是,它只发送一个应用程序的输出而不发送另一个应用程序的输出。

执行服务器和客户端之间的连接时执行以下功能:

private function startProc($client) {
    $this->output("Start a client process");
    $pid = pcntl_fork();
    if($pid == -1) {
        $this->output("fork terminated!");
    }
    elseif($pid) { // process
        $client->setPid($pid);
    }
    else {
        $this->output("Starting app1 data pipe...");
        exit($this->launchAppOneProc($client));

        $this->output("Starting app2 data pipe...");
        exit($this->launchAppTwoProc($client));
    }
}

好的,一旦客户端和服务器之间的连接完成,就会执行此功能。如您所见,我创建了一个新进程,然后执行两个方法:launchAppOneProc和launchAppTwoProc。这两个函数包含以下代码:

private function launchAppOneProc($client) {
    while (@ ob_end_flush()); // end all output buffers if any

    while (!feof($this->appone_proc))
    {   
        $appone_text = fread($this->appone_proc, 4096);
        $this->send($client, $appone_text);
        flush();
    }

    $this->output("AppOne has stopped running!");
}

上面的函数与launchAppTwoProc()的函数相同。函数$ this->输出打印指定到server_class.php终端的文本

所以问题是它只执行launchAppOneProc()函数而不执行下一个函数launchAppTwoProc()。

关于如何执行这两个功能的任何想法?

谢谢 大卫

1 个答案:

答案 0 :(得分:0)

好的,我找到了解决问题的方法。为了清除一些混淆,我有两个在后台运行并写入缓冲区的应用程序。当客户端连接到服务器时,它们连接到两个缓冲区并开始接收数据。所以我所做的就是为每个频道创建一个新流程。当客户端连接到服务器时,会创建两个进程并将其分配给客户端。每个进程都连接到一个缓冲区并开始向客户端发送数据。

private function startProc($client) {
    $this->output("Start a client process");

    for ($i = 0; $i < 2; ++$i) {
        // Create new process.
        $pid = pcntl_fork();

        switch ($pid) {
            case -1: // Failed to create new process.
                $this->output("Failed to create new process!");
                break;

            case 0: // Child process created, execute code...
                switch ($i) {
                    case 0:
                        $this->output("Connect to AppOne data pipe...");
                        $this->launchAppOneProc($client);
                        break;

                    case 1:
                        $this->output("Connect to AppTwo data pipe...");
                        $this->launchAppTwoProc($client);
                        break;
                }

            default: // Back to parent.
                switch ($i) {
                    case 0:
                        $client->setAppOnePid($pid);
                        break;
                    case 1:
                        $client->setAppTwoPid($pid);
                        break;
                }
        }
    }
}

我知道我可以使用数组来存储进程ID等。但是现在,这可行。一旦客户端断开连接,刚离开的客户端的每个进程都必须如此终止:

posix_kill($client->getAppOnePid(), SIGTERM);
posix_kill($client->getAppTwoPid(), SIGTERM);

我希望这有意义并帮助遇到同样问题的任何人。