php pcntl开启多进程执行任务

2022-10-11 21:15:47 182 0
魁首哥

开发的过程中,偶尔会碰到将大量的数据进行同步,PHP作为单线程,不能使用多线程的思路来发挥多核的优势。

虽然不能创建线程,但是我们可以创建进程,一样可以达到利用多核CPU的目的。

涉及到资源的并发使用问题,多线程、多进程都需要并发安全地使用资源。

简单例子

实验代码

ceshi.php

  

运行结果

任务执行结果

上图中我们开启了五个 进程 ,每个进程执行一段任务,隔离了任务,防止不同进程执行相同的任务。

不知道大家有没有注意到,上图中父进程退出了,为什么还能打印出进程号为 594 号的输出呢。这是因为 子进程继承了父进程打开的文件描述符 ,如:标准输出(stdout)、标准输入(stdin)、标准错误(stderr)。这三个描述符都是对应终端的,所以会输出到终端,就是我们执行命令的窗口。

守护进程实现

上面脚本如果是一个无限循环,日志将会一直打印,当用户 Session终端 退出,任务也会随着退出。这时候我们就需要使用 守护进程 去实现这个任务进程,守护进程一旦执行,终端关闭与否,任务进程都会运行。关闭守护进程可以使用kill命令,或者在任务执行完成之后直接退出就可以。

实验代码

ceshi.php

  0) {
		//父进程退出,子进程不是进程组长,以便接下来顺利创建新会话
    exit;
}

posix_setsid();  // 脱离终端,设置新的session会话
posix_setuid(33);  // 设置进程用户
posix_setgid(33);  // 设置进程组
fclose(STDOUT);  // 关闭标准输出
fclose(STDIN);  // 关闭标准输入
fclose(STDERR);   // 关闭标准错误
cli_set_process_title("ceshi"); // 设置进程名字

// 循环创建子进程处理任务
for ($i = 0; $i < 5; $i++) {
    $id = pcntl_fork();
    if ($id == -1) {
        die("pcntl fork failed");
    } elseif($id) {
        // parent process
        continue;
    } else {
        // child process
        task($i * 1000);
        exit;
    }
}
  

运行结果

php ceshi.php

守护进程结果截图

守护进程的代码里面已经注释了实现逻辑,截图也已经将关键的命令以及结果做了注释,大家可以结合着看,我这里就不多做介绍。

实现守护进程的过程中我自己踩到一个坑,这里分享下,避免踩坑:

在关闭标准输入、标准输出、标准错误的文件描述符之后,就不要再使用 printf 函数,这个函数会将结果打印到标准输出,如果强行打印会致使程序退出, ps 也查不到相关运行的进程。

收藏
分享
海报
0 条评论
182
上一篇:截至2021年12月31日24时河南省新型冠状病毒肺炎疫情最新情况 下一篇:PHP开发程序应该注意的42个优化准则

本站已关闭游客评论,请登录或者注册后再评论吧~

忘记密码?

图形验证码