至于php_pcntl扩展如何安装开启这里就不介绍了,只分析pcntl_fork()这个函数自己。php
1.$one = 123; 2.$one++; 3.$two = time(); 4.$pid = []; 5.$pid = pcntl_fork(); 6.$three = time();
当:pcntl_fork()函数执行的时候,会建立一个子进程。子进程会复制当前进程,也就是父进程的全部:数据,代码,还有状态。react
1.当pcntl_fork()建立子进程成功后,在父进程内,返回0,在子进程内返回自身的进程号,失败则返回-1linux
2.子进程会复制父进程的代码,数据。那么就说明:子,父进程拥有的代码和数据会如出一辙。windows
3.重点:子进程会复制父进程的状态,那么就有上面的示例代码:在第五行执行了pcntl_fork,那么建立出的子进程,代码也是从第五行开始执行的。又子进程复制了数据,代码。因此,在子进程内同理存在:$one,$two等变量数组
for ($i = 0; $i < 3; $i++) { $pid = pcntl_fork(); } sleep(30);
那么:上面的for循环,实际会产生多少个子进程?答案是7个,在linux下,用ps命令将能够看到8个进程(1个父进程,7个子进程)
缘由:父进程在$i=0时,建立出一个子进程0,此时的子进程,还会继续执行循环。建立出属于本身的子进程。同理:$i=1时也会这样……服务器
参考:https://www.jianshu.com/p/5f383a85d663swoole
PHP建立多进程的Demo示例:多线程
<?php /** * PHP多进程和多线程的处理 */ //建立socket监听 $socketserv = stream_socket_server('tcp://0.0.0.0:8000', $errno, $errstr); //建立5个子进程 for ($i = 0; $i < 5; $i++) { //使用pcntl_fork()建立进程,会返回pid,若是pid==0,则表示主进程 if (pcntl_fork() == 0) { //循环监听 while (true) { $conn = stream_socket_accept($socketserv); //若是监听失败,则从新去监听 if(!$conn){ continue; } //读取流信息,读取的大小 是9000 $request = fread($conn, 9000); //写入响应 $response = 'hello'; fwrite($conn, $response); //关闭流 fclose($conn); } //建立完全部的子进程,而后退出 exit(0); } }
运行 php stream_socket.php,使用ps -ef 查看进程,会看到多出了以下的5个进程:异步
扩展:PHP的异步非阻塞模型 Reactor:socket
Reactor有4个核心的操做:
(C语言用函数指针实现,JS能够用匿名函数,PHP能够用匿名函数、对象方法数组、字符串函数名)
Reactor只是一个事件发生器,实际对socket句柄的操做,如connect/accept、send/recv、close是在callback中完成的。
具体编码可参考下面的代码(须要先安装Reactor扩展):
Reactor模型还能够与多进程、多线程结合起来用,既实现异步非阻塞IO,又利用到多核。
目前流行的异步服务器程序都是这样的方式:如