php是单进程语言,但是也有办法支持多进程

第一步的创建子进程,用到的是pcntl_fork()函数,函数返回值通常为0,失败时返回-1。我先举一个创建子进程的直观小栗子(抄袭):

$ppid = posix_getpid();
$pid = pcntl_fork();
if ($pid == -1) {
throw new Exception('fork子进程失败!');
} elseif ($pid > 0) {
cli_set_process_title("我是父进程,我的进程id是{$ppid}.");
     sleep(30); // 保持30秒,确保能被ps查到
} else {
$cpid = posix_getpid();
cli_set_process_title("我是{$ppid}的子进程,我的进程id是{$cpid}.");
sleep(30);
}
    第二步的管理子进程,使用的是信号。简单来说,就是父进程里使用两个函数pcntl_signal()和pcntl_signal_dispatch,负责给子进程安装信号处理器和分发工作。  这个步骤就先如此简单介绍一下,因为涉及到一个回调函数的概念,以后我会补上更全面地内容。

    第三步的处理子进程,也是需要两个函数。一个是发送终止信号的posix_kill()函数,一个是等待子进程状态的pcntl_waitpid()函数,这样就可以实现跟子进程共同完成的任务的目的了。

    所以,后端开发就是这样,很多以为会复杂的东西,其实步骤很清晰,基本都属于用到的知识多,用到的函数却不多这样。所以入门的时候就硬着头皮学下去好了,要相信自己总有一天可以很清楚明白。

PHP使用PCNTL系列的函数也能做到多进程处理一个事务。比如我需要从数据库中获取80w条的数据,再做一系列后续的处理,这个时候,用单进程?你可以等到明年今天了。。。所以应该使用pcntl函数了。

假设我想要启动20个进程,将1-80w的数据分成20份来做,主进程等待所有子进程都结束了才退出:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
$max  = 800000;
$workers  = 20;
 
$pids  = array ();
for ( $i  = 0; $i  < $workers ; $i ++){
     $pids [ $i ] = pcntl_fork();
     switch  ( $pids [ $i ]) {
         case  -1:
             echo  "fork error : {$i} \r\n" ;
             exit ;
         case  0:
             $param  = array (
                 'lastid'  => $max  / $workers  * $i ,
                 'maxid'  => $max  / $workers  * ( $i +1),
             );
             $this ->executeWorker( $input , $output , $param );
             exit ;
         default :
             break ;
     }
}
 
foreach  ( $pids  as  $i  => $pid ) {
     if ( $pid ) {
         pcntl_waitpid( $pid , $status );
     }
}

这里当pcntl_fork出来以后,会返回一个pid值,这个pid在子进程中看是0,在父进程中看是子进程的pid(>0),如果pid为-1说明fork出错了。

使用一个$pids数组就可以让主进程等候所有进程完结之后再结束了

猜你喜欢

转载自www.cnblogs.com/liliuguang/p/12610377.html