PHP 多进程与信号处理:实现高效并发

2025-12-27 5874阅读

在 PHP 开发中,多进程编程是提升应用性能的重要手段。通过创建多个子进程,可以并行处理任务,充分利用多核 CPU 资源。而信号处理则为进程间的通信和控制提供了一种机制。

多进程创建

PHP 提供了 pcntl_fork 函数用于创建子进程。以下是一个简单示例:

<?php
$pid = pcntl_fork();
if ($pid == -1) {
    die('fork 失败');
} elseif ($pid) {
    // 父进程逻辑
    echo "父进程,子进程 ID:$pid\n";
} else {
    // 子进程逻辑
    echo "子进程,ID:". posix_getpid(). "\n";
    exit(0);
}

在上述代码中,pcntl_fork 会返回两次。在父进程中返回子进程 ID,在子进程中返回 0。通过判断返回值,我们可以分别处理父、子进程的逻辑。

信号处理

信号是进程间通信的一种方式。PHP 可以通过 pcntl_signal 函数注册信号处理函数。例如,处理 SIGTERM 信号:

<?php
pcntl_signal(SIGTERM, function ($signo) {
    echo "收到 SIGTERM 信号,进程即将退出\n";
    exit(0);
});
// 模拟进程运行
while (true) {
    sleep(1);
}

当外部发送 SIGTERM 信号(如 kill -TERM <进程 ID>)时,注册的信号处理函数会被调用,执行相应的清理操作后退出进程。

多进程与信号结合

在实际应用中,我们可以利用多进程处理任务,并通过信号控制子进程。比如,一个主进程创建多个工作子进程,当需要停止时,发送信号通知子进程优雅退出:

<?php
$workers = [];
// 创建 3 个子进程
for ($i = 0; $i < 3; $i++) {
    $pid = pcntl_fork();
    if ($pid == -1) {
        die('fork 失败');
    } elseif ($pid) {
        $workers[] = $pid;
    } else {
        // 子进程逻辑,模拟工作
        while (true) {
            echo "子进程 ". posix_getpid(). " 工作中...\n";
            sleep(1);
        }
    }
}
// 注册信号处理函数
pcntl_signal(SIGTERM, function ($signo) use ($workers) {
    foreach ($workers as $pid) {
        posix_kill($pid, SIGTERM); // 向子进程发送 SIGTERM 信号
    }
    echo "主进程收到 SIGTERM,等待子进程退出\n";
    foreach ($workers as $pid) {
        pcntl_waitpid($pid, $status); // 等待子进程退出
    }
    exit(0);
});
// 主进程等待信号
while (true) {
    pcntl_signal_dispatch(); // 处理信号
    sleep(1);
}

在这个示例中,主进程创建了多个子进程。当收到 SIGTERM 信号时,主进程向子进程发送信号,然后等待子进程退出,实现了进程的优雅关闭。

总结

PHP 的多进程编程结合信号处理,为构建高性能、可控制的应用提供了有力支持。通过合理利用这些特性,可以提升系统的并发处理能力和稳定性。在实际开发中,需注意资源管理和信号处理的细节,确保程序的健壮性。

文章版权声明:除非注明,否则均为Dark零点博客原创文章,转载或复制请以超链接形式并注明出处。