php多进程

php多进程编程

爱⌒轻易说出口 提交于 2020-01-16 15:20:35
php多进程编程 PHP的进程控制支持实现了Unix方式的进程创建, 程序执行, 信号处理以及进程的中断。 进程控制不能被应用在Web服务器环境,当其被用于Web服务环境时可能会带来意外的结果。 pcntl函数 pcntl_fork() :在当前进程当前位置产生分支(子进程)。译注:fork是创建了一个子进程,父进程和子进程 都从fork的位置开始向下继续执行,不同的是父进程执行过程中,得到的fork返回值为子进程 号,而子进程得到的是0 <?php $pid = pcntl_fork(); //父进程和子进程都会执行下面代码 if ($pid == -1) { //错误处理:创建子进程失败时返回-1. die('could not fork'); } else if ($pid) { //父进程会得到子进程号,所以这里是父进程执行的逻辑 pcntl_wait($status); //等待子进程中断,防止子进程成为僵尸进程。 } else { //子进程得到的$pid为0, 所以这里是子进程执行的逻辑。 exit();//子进程执行完后应该退出,不然会继续执行后面的逻辑 } pcntl_wait(int &$status[, int $options = 0]) :等待或返回fork的子进程状态,相当于pcntl_waitpid(-1,int &$status[,int

多进程下的文件描述符

风流意气都作罢 提交于 2020-01-07 07:52:30
【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>> 多进程下的文件描述符 我们都知道fork之后, 子进程继承了父进程的文件描述符. 但是这是什么意思? 如果父子进程或多个子进程同时操作这个文件描述符会如何? 奇怪的表现 脚本的基本逻辑是父进程读取要处理的文件是计算行数, 然后根据配置的子进程个数fork子进程,子进程处理某一范围的数据,比如子进程1处理1到10行, 子进程2处理11到20. 因为对这个文件的处理是只读操作, 所以没有进行文件拆分,而是直接使用继承的文件描述符, 各子进程移动到自己处理的范围进行处理. 但是在测试的时候, 发现有些子进程总是无法读到数据, strace 调试发现read(2)返回0. 但是增加fseek之后,又正常了, 见当时代码注释: //开发时发现如果没有这个fseek, 会导致$proc_idx=0的那个子进程fgets读不到数据,strace显示read返回0 //原因不明 fseek($order_file, ftell($order_file)); while(($line_no <= $stop) && $line = fgets($order_file, 4096)) { .... } 可以看到这个fseek到ftell完全是没有用的,但加了这句这后就就正常了. 真是匪夷所思. 开发时, 一开始是正常的,

多进程案例

匆匆过客 提交于 2019-12-10 01:26:24
PHP的pcntl多进程 2013-07-26 18:03 by 轩脉刃, 11446 阅读, 5 评论, 收藏 , 编辑 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(

php多进程实现

不问归期 提交于 2019-12-10 01:20:31
PHP 多进程实现 PHP有一组进程控制函数(编译时需要–enable-pcntl与posix扩展),使得php能在nginx系统中实现跟c一样的创建子进程、使用exec函数执行程序、处理信号等功能。 CentOS 6 下yum安装php的,默认是不安装pcntl的,因此需要单独编译安装,首先下载对应版本的php,解压后 [plain] view plain copy print ? cd php-version/ext/pcntl phpize ./configure && make && make install cp /usr/lib/php/modules/pcntl.so /usr/lib64/php/modules/pcntl.so echo "extension=pcntl.so" >> /etc/php.ini /etc/init.d/httpd restart 方便极了。 下面是示例代码: [php] view plain copy print ? <?php header('content-type:text/html;charset=utf-8' ); // 必须加载扩展 if (!function_exists("pcntl_fork")) { die("pcntl extention is must !"); } //总进程的数量 $totals = 3;

php多进程处理

*爱你&永不变心* 提交于 2019-12-09 23:55:06
php多进程处理 往往我们会碰到一个情况,需要写一个脚本,这个脚本要处理的数据量极大,单进程处理脚本非常慢,那么这个时候就会想到使用多进程或者多线程的方式了。 我习惯使用多进程的方式,php中使用多进程的时候需要使用pcntl,pcntl的使用可以看这个 PHP的pcntl多进程 但是这里有一个问题,一个主进程把任务分成n个部分,然后把任务分配给多个子进程,但是任务可能是有返回值的,所有的子进程处理完返回值以后需要把返回值返回给主进程。 这个就涉及到了进程间通信了。进程间通信可以使用的方法当然很多了,比如用redis,用数据库,用文件等。 php中最简单的要算shmop相关函数了。 shmop_open shmop_read shmop_write shmop_size shmop_delete 那怎么让一个类很容易有多进程处理的能力呢?可以使用php的trait,创建一个PcntlTrait,所有需要有多进程处理功能的类就use 这个trait就行。 PcntlTrait代码如下: <?php namespace App\Console\Commands; trait PcntlTrait { private $workers = 1; public function worker($count) { $this->workers = $count; } public

PHP并发IO编程之路

Deadly 提交于 2019-12-04 03:56:53
并发 IO 问 题一直是后端编程中的技术挑战,从最早的同步阻塞Fork进程,到多进程/多线程,到现在的异步IO、协程。PHP程序员因为有强大的LAMP框架,对底 层方面的知识知之甚少,本文目的就是详细介绍PHP进行并发IO编程的各种尝试,最后再介绍Swoole的使用,深入浅出全面理解并发IO问题。 多进程 / 多线程同步阻塞 最早的服务器端程序都是通过多进程、多线程来解决并发 IO 的问题。进程模型出现的最早,从 Unix 系统诞生就开始有了进程的概念。 最早的服务器端程序一般都是 Accept 一个客户端连接就创建一个进程,然后子进程进入循环同步阻塞地与客户端连接进行交互,收发处理数据。 多线程模式出现要晚一些,线程与进程相比更轻量,而且线程之间是共享内存堆栈 的,所以不同的线程之间交互非常容易实现。比如聊天室这样的程序,客户端连接之间可以交互,比聊天室中的玩家可以任意的其他人发消息。用多线程模式实现非 常简单,线程中可以直接读写某一个客户端连接。而多进程模式就要用到管道、消息队列、共享内存实现数据交互,统称进程间通信( IPC )复杂的技术才能实现。 代码实例: 多进程 / 线程模型的流程是 创建一个 socket ,绑定服务器端口( bind ),监听端口( listen ),在 PHP 中用 stream_socket_server 一个函数就能完成上面 3 个步骤

PHP并发IO编程之路

非 Y 不嫁゛ 提交于 2019-12-04 03:56:42
并发 IO 问 题一直是服务器端编程中的技术难题,从最早的同步阻塞直接Fork进程,到Worker进程池/线程池,到现在的异步IO、协程。PHP程序员因为有强大 的LAMP框架,对这类底层方面的知识知之甚少,本文目的就是详细介绍PHP进行并发IO编程的各种尝试,最后再介绍Swoole的使用,深入浅出全面解 析并发IO问题。 多进程 / 多线程同步阻塞 最早的服务器端程序都是通过多进程、多线程来解决并发 IO 的问题。进程模型出现的最早,从 Unix 系统诞生就开始有了进程的概念。 最早的服务器端程序一般都是 Accept 一个客户端连接就创建一个进程,然后子进程进入循环同步阻塞地与客户端连接进行交互,收发处理数据。 多线程模式出现要晚一些,线程与进程相比更轻量,而且线程之间是共享内存堆栈 的,所以不同的线程之间交互非常容易实现。比如聊天室这样的程序,客户端连接之间可以交互,比聊天室中的玩家可以任意的其他人发消息。用多线程模式实现非 常简单,线程中可以直接向某一个客户端连接发送数据。而多进程模式就要用到管道、消息队列、共享内存,统称进程间通信( IPC )复杂的技术才能实现。 代码实例: 多进程 / 线程模型的流程是 创建一个 socket ,绑定服务器端口( bind ),监听端口( listen ),在 PHP 中用 stream_socket_server 一个函数就能完成上面

PHP多进程简单实例小结

夙愿已清 提交于 2019-12-04 00:27:58
本文实例讲述了PHP多进程。分享给大家供大家参考,具体如下: PHP创建多进程需要使用到pcntl模块 在编译时加上--enable-pcntl打开进程控制支持,不是Unix类系统不支持此模块 php官网介绍http://php.net/manual/zh/book.pcntl.php,创建子进程需要使用到pcntl_fork(),文档上介绍该函数说 ,pcntl_fork — 在当前进程当前位置产生分支(子进程)。 译注:fork是创建了一个子进程,父进程和子进程 都从fork的位置开始向下继续执行,不同的是父进程执行过程中,得到的fork返回值为子进程号,而子进程得到的是0。失败时,在 父进程上下文返回-1,不会创建子进程,并且会引发一个PHP错误。 ? 1 2 3 4 <?php $pid = pcntl_fork(); var_dumP( $pid ); ?> 运行上面面代码,会返回两个值,一个是0和子进程的PID; ? 1 2 3 4 5 6 7 <?php $i =0; while ( $i !=5){ $pid = pcntl_fork(); echo "进程ID:" . $pid . "==" . $i ++.PHP_EOL; } ?> 运行上面程序发现进程数指数增长 刚好是2^5=32个;原因是每一条都执行了while循环,到最后成了进程的指数增长—

PHP进程间通信

爷,独闯天下 提交于 2019-11-30 07:41:12
PHP作为解释器运行通过线程或者进程都能实现(如果使用Apache,那么就可能使用多线程模型。使用php-fpm,就是使用多进程模型,这里以多进程模型解释)。服务器每接收到一个请求就要起一个PHP进程,平均一个PHP进程消耗内存2M左右(默认最大为8M,参数可以设置)。独立的进程让PHP能专一的做自己的解释工作,程序员也从复杂的代码逻辑中走出来,不用担心资源的竞争和各种锁问题。独立进程虽好但这也导致想通过多进程或者异步来提速成本非常的高(主要是开发难度)。如果一定要通过PHP实现多进程和异步其实是很容易做到的。 PHP有很多第三方扩展,比如Swoole能让PHP像Node一样实现异步。PHP官方扩展库 pcntl_* 能很简单的实现多进程。扩展虽好,但实际应用时切忌要慎重,便利的同时风险也来了。比如对多进程的控制,处理不好很容易导致程序死锁,CPU内存爆表、服务器宕机。异步回调的Coding方式与PHP本身的编程思想有一定出入,驾驭不好也是灾难。 当然也不能说的太吓人,在实际的项目中我们有很多场景不得不考虑通过多进程或者异步来优化程序。这里举一个很常见的例子 『发送消息通知』 ,比如短信和邮件。这里说一个实际的场景:企业需要给200W用户发短信通知 ,短信接口支持最大100次/秒的调用频率 ,短信接口每次调用耗时300毫秒。如果单进程跑脚本的话,需要7天才能把短信发完。

Swoole进程模型

北城余情 提交于 2019-11-28 19:59:45
进程 什么是进程 进程 Process 是计算机中的程序关于某数据集合上的一次运行活动,是系统分配资源和调度的基本单位,是操作系统结构的基础。在早期面向进程设计的计算机结构中,进程是程序的基本执行实体。在当代面向线程设计的计算机结构中,进程是线程的容器。简单来说,程序是指令、数据以及其组织形式的描述,而进程则是程序的实体。 在操作系统中,进程表示正在运行的程序,例如在终端中使用PHP命令运行PHP脚本,此时就相当于创建了一个进程,这个进程会在系统中驻存,申请属于它自己的内存空间和系统资源,并且运行相应的程序。 $ php build.php <?php //获取当前进程的PID echo posix_getpid(); //修改所在进程的名称 swoole_set_process_name("swoole process master"); //模拟持续运行100秒的程序 sleep(100);//持续运行100秒的目的是为了在进程中可以查看而不至于很快结束 运行程序 $ php build.php 71 查看进程 $ ps aux | grep 71 root 1 0.0 0.1 18188 1712 pts/0 Ss+ 11:07 0:00 /bin/bash root 71 0.0 3.0 340468 30788 pts/2 S+ 13:41 0:00 swoole