来源:https://www.jianshu.com/p/de0b74f58f50

pcntl是一个可以利用操作系统的fork系统调用在PHP中实现多线程的进程控制扩展,当使用fork系统调用后执行的代码将会是并行的。pcntl仅适用于Linux平台的CLI模式下使用。

PHP官方没有提供多线程的扩展,在pecl中有一个pthread扩展提供了多线程的特性,此版本仅在线程安全版本中可用。

创建子进程pcntl_fork

int pcntl_fork(void)

pcntl_fork函数执行时会在当前进程下创建一个子进程,子进程与父进程在PID和PPID上会不同。

子进程会复制父进程中所有的数据、代码、状态等信息。当使用pcntl_fork成功创建子进程后,子进程会复制父进程的代码和数据。此时父进程和子进程拥有相同的代码和数据。子进程也会复制父进程的状态。

当使用pcntl_fork创建子进程,如果成功则会在父进程中将会返回0,在子进程中会返回自身的进程编号PID。如果创建失败则返回-1

使用pcntl_fork创建的进程只是一个分支节点,相当于一个标记,父进程完成后子进程会从标记处继续执行,也就是说在pcntl_fork之后的代码分别会被父进程和子进程执行两遍,而两个进程在执行过程中得到的返回值却是不同的,因此才可以分离父子进程执行不同的代码。

在Linux环境下可使用ps命令查看进程

<?php
$pid = pcntl_fork();
if($pid > 0){
//父进程
exit(0);
}elseif($pid == 0){
//子进程
exit(0);
}

多进程和多线程的作用相同,区别主要在于

  • 多个线程是在同一个进程内的,线程之间可以共享内存变量而实现线程间的通信。
  • 线程比进程更加轻量级,进程要比线程更加消耗系统资源。

多线程存在的问题主要有

  • 线程读写变量存在着同步问题需要加锁
  • 锁粒度过大会存在性能问题,会导致只有一个线程在运行,其它线程都在等待锁,也就无法实现并行。
  • 同时使用多个锁时逻辑复杂,一旦某个锁没有被正确释放可能会发生线程死锁。
  • 某个线程发生致命错误会导致整个进程崩溃

相对而言多进程更为稳定,可利用进程间通信IPC技术实现数据共享。多进程通信的方式主要包括

  • 共享内存
    共享内存和线程间读写变量时一样的,都需要加锁,同时也存在同步、死锁等问题。
  • 消息队列
    消息队列采用多个子进程抢占队列的模式,性能较好。
  • 管道、UnixSock、TCP、UDP
    可以使用read/write来传递数据,TCP/UDP使用socket来通信,子进程可以分布运行。

利用fork系统调用可以实现并发的TCP服务器,主进程accept客户端连接。当有新的连接到来时直接fork一个子进程,子进程中循环recv/send处理数据。这种模式在请求量不多的情况下很实用,例如FTP服务器。

在过去多数Linux程序都时采用这种模式,简单高效,代码量少。当有几百个并发的情况下表现不错,但在大并发的情况下消耗就会过大。

例如:每个子进程都能创建一个与之对应的文件,父进程也创建一个属于自己的文件。

<?php
$socket = socket_create(AF_INET, SOCK_STREAM, 0);
if($socket < 0){
$errmsg = socket_strerror($socket);
echo "failed to create socket: {$errmsg}".PHP_EOL;
exit;
} $host = "0.0.0.0";
$port = 9601;
$ret = socket_bind($socket, $host, $port);
if($ret < 0){
echo "failed to bind socket: {$ret}".PHP_EOL;
exit;
} $ret = socket_listen($socket, 0);
if($ret < 0){
$errmsg = socket_strerror($ret);
echo "failed to listen: {$errmsg}".PHP_EOL;
exit;
} while(pcntl_fork() == 0){
$connection = @socket_accept($socket);
if(pcntl_fork() == 0){
$recv = socket_read($connection ,8192);
$data = "serverr: {$recv}"; socket_write($connection ,$data);
socket_close($connection);
exit(0);
}else{
socket_close($connection);
}
}
 
 

PHP pcntl的更多相关文章

  1. PHP的pcntl多进程

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

  2. CLI下另一种多进程实现方式----PCNTL

    有些时候,你需要对一些脚本进行优化,以期跑的更快,在更短的时间内完成任务.PCNTL是一个不错的选择,它可以fork多个进程,来协同完成一个任务,理论上完成的时间将会和进程数成反比. 不过,PCNTL ...

  3. Linux系统中为php添加pcntl扩展的方法

    1.首先看下 phpize命令 所在的目录  (ps:我的目录/usr/bin/phpize)如果没有找到的话 执行安装yum install php53_devel (ps:请注意自己的版本) 安装 ...

  4. 加载 pcntl 多进程

    加载 pcntl 有两种方式 一种重新编译安装,在编译时加 --enable-pcntl ./configure --prefix=/usr/local/php --with-mysql=/usr/l ...

  5. 安装pdo.so和pdo_mysql.so还有pcntl.so扩展到php中

    1.下载源码,解压tar -xzvf php-5.4.20.tar.gz cd  /usr/local/src/php-5.4.20/ext/pdo /usr/local/php/bin/phpize ...

  6. mac下安装pcntl

     Now you need to find out what version of PHP is installed on OSX $ php -vPHP 5.3.10 with Suhosin-Pa ...

  7. (转载)PCNTL函数族--PHP多进程编程

    (转载)http://www.cnblogs.com/zox2011/archive/2013/02/19/2917448.html php有一组进程控制函数,使得php能在*nix系统中实现跟c一样 ...

  8. MAMP 环境下为 php 添加 pcntl 扩展

    前言: pcntl 介绍 pcntl 扩展可以支持 PHP 的多线程操作.(非Unix类系统不支持此模块) phpize 介绍 phpize 可以用来给 PHP 动态的添加扩展.比如编译 PHP 时忘 ...

  9. php添加pcntl扩展(Linux)

    pcntl扩展可以支持php的多线程操作(仅限linux)原本需要重新编译PHP的后面configrue提示加上--enable-pcntl 由于我的php是采用yum安装的,所以不能采用上面的方式下 ...

  10. 安装pcntl以实现php多进程

    pcntl 扩展包一般就在php源码的ext目录下. cd ./ext/pcntl /opt/server/php5/bin/phpize ./configure \ --with-php-confi ...

随机推荐

  1. linux压缩及归档

    一.解析 压缩:把大文件,通过压缩成一个比之前小的文件. 归档(打包):把多个文件,归档成一个文件. 二.压缩 1.zip(归档压缩,可以压缩目录,要保存源文件) 压缩:zip  压缩后的文件名 压缩 ...

  2. Ruby学习计划-(1)搭建开发环境

    环境搭建        工欲善其事,必先利其器.要学习一门新的语言当然也需要搭建好开发环境,这样才能更加高效的完成工作提高自身的工作效率.PS:由于自己使用的是MacBookPro,因此之后的所有问题 ...

  3. F - F HDU - 1173(二维化一维-思维)

    F - F HDU - 1173 一个邮递员每次只能从邮局拿走一封信送信.在一个二维的直角坐标系中,邮递员只能朝四个方向移动,正北.正东.正南.正西. 有n个需要收信的地址,现在需要你帮助找到一个地方 ...

  4. B. The Monster and the Squirrel

    B. The Monster and the Squirrel Ari the monster always wakes up very early with the first ray of the ...

  5. CF632(div.2)C. Eugene and an array

    https://codeforces.ml/contest/1333/problem/C 大概题意是规定和为0的数组为不合格数组,询问给定数组中共有多少个合格子数组. 解题 子数组的数量 一个长度为 ...

  6. 谁给你说的 Ubuntu 不可以输入中文

    文章更新于:2020-04-04 按照惯例,需要的文件附上链接放在文首 文件名:sogoupinyin_2.3.1.0112_amd64.deb 文件大小:25.5 MB 下载链接:https://w ...

  7. 如何在VMwareWorkstation中安装Ubuntu系统

    文章更新于:2020-03-17 注:如果安装之后重启停留在Write through,则关闭客户机,将 ISO 镜像换为物理光驱,或取消勾选开机连接.再次开机即可正常进入系统. 文章目录 一.安装环 ...

  8. Java第八天,抽象的概念是什么?如何完成抽象类的实现?

    抽象 面向对象编程中,抽象是一个很重要的概念,那么抽象有什么需要注意的地方呢?请熟记以下知识点. 如果父类当中的方法不确定如何进行方法体的实现,则这个方法就是抽象方法. 抽象方法只需要在方法前面加上a ...

  9. MODIS系列之NDVI(MOD13Q1)一:数据下载(一)基于插件

    引言: 写MODIS数据处理这个系列文章的初衷,主要是为了分享本人处理MODIS数据方面的一些经验.鉴于网上对这方面系统性的总结还比较少,我搜集资料时也是走了许多的弯路,因此希望通过此文让初学者能够更 ...

  10. Array(数组)对象-->数组的删除

    1.数组的删除: 用delete操作符删除特定的元素 删除元素的位置只是被留空了,为undefined值 举例:删除下面数组中的第二个元素 var arr = [1,2,3,4,5]; /*删除第二个 ...