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命令查看进程

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

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

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

多线程存在的问题主要有

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

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

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

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

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

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

copycode
<?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);
    }
}
copycode

使用实例:

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

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

copycode
$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);
  }
}
copycode

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

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

分类: 知识 标签: 暂无标签

评论

全部评论 9

  1. kursus bahasa inggris karyawan
    kursus bahasa inggris karyawan
    Google Chrome Linux
    Informative article, exactly what I needed.
  2. cara belajar bahasa inggris dari nol
    cara belajar bahasa inggris dari nol
    Google Chrome Windows 10

    I am extremely impressed with your writing skills as well
    as with the layout on your weblog. Is this a paid theme or did you customize it
    yourself? Either way keep up the nice quality writing, it is rare to see a nice
    blog like this one these days.

  3. HanimeHentai.ru
    HanimeHentai.ru
    Google Chrome Linux
    Outstanding story there. What occurred after?

    Thanks!

  4. pusat genset surabaya
    pusat genset surabaya
    Google Chrome Linux

    I’m not that much of a online reader to be honest but your blogs really nice,
    keep it up! I'll go ahead and bookmark your site to come back down the
    road. Cheers

  5. ремонт техники в мск
    ремонт техники в мск
    Google Chrome Windows 10

    Профессиональный сервисный центр по ремонту бытовой техники с выездом на дом.
    Мы предлагаем:ремонт бытовой техники в мск
    Наши мастера оперативно устранят неисправности вашего устройства в сервисе или с выездом на дом!

  6. Ремонт iphone в Москве
    Ремонт iphone в Москве
    Google Chrome Windows 10

    Наши специалисты предлагает профессиональный выездной ремонт iphone всех типов и брендов. Мы понимаем, насколько важны для вас ваши iPhone, и обеспечиваем ремонт высочайшего уровня. Наши профессиональные техники проводят ремонтные работы с высокой скоростью и точностью, используя только качественные детали, что гарантирует долговечность и надежность проведенных ремонтов.
    Наиболее частые неисправности, с которыми сталкиваются пользователи смартфонов Apple, включают поврежденный экран, неисправности аккумулятора, неисправности программного обеспечения, неисправности разъемов и механические повреждения. Для устранения этих поломок наши профессиональные техники проводят ремонт экранов, батарей, ПО, разъемов и механических компонентов. Обратившись к нам, вы обеспечиваете себе долговечный и надежный выездной ремонт iphone.
    Подробная информация размещена на сайте: https://remont-iphone-sot.ru

  7. Сколько стоит отремонтировать прибор ночного видения PARD в Самаре

    Профессиональный сервисный центр по ремонту техники в Самаре.
    Мы предлагаем: Сколько стоит отремонтировать прибор ночного видения PARD
    Наши мастера оперативно устранят неисправности вашего устройства в сервисе или с выездом на дом!

  8. Ремонт холодильников Gorenje Москва

    Предлагаем услуги профессиональных инженеров офицальной мастерской.
    Еслли вы искали ремонт холодильников gorenje, можете посмотреть на сайте: ремонт холодильников gorenje
    Наши мастера оперативно устранят неисправности вашего устройства в сервисе или с выездом на дом!

  9. Ремонт духовых шкафов в Москве

    Наши специалисты предлагает профессиональный сервис ремонта духовых шкафов адреса любых брендов и моделей. Мы понимаем, насколько необходимы вам ваши духовые шкафы, и готовы предложить сервис наилучшего качества. Наши профессиональные техники оперативно и тщательно выполняют работу, используя только качественные детали, что гарантирует долговечность и надежность проведенных ремонтов.
    Наиболее общие проблемы, с которыми сталкиваются пользователи духовок, включают неработающие нагревательные элементы, поломку таймера, поломку дверцы, неисправность контроллера, проблемы с конвекцией и неработающие датчики. Для устранения этих поломок наши профессиональные техники выполняют ремонт нагревательных элементов, термостатов, таймеров, дверец, контроллеров, вентиляторов и электроники. Доверив ремонт нам, вы обеспечиваете себе надежный и долговечный вызвать мастера по ремонту духовых шкафов рядом.
    Подробная информация доступна на сайте: https://remont-duhovyh-shkafov-ace.ru

目录