zoukankan      html  css  js  c++  java
  • php是单进程语言,但是也有办法支持多进程

      目前项目运用到队列,我用redis作为队列服务器,在这个过程中,每次lpush参数用rpop取出,但需要一个常驻LINUX系统的多进程pcntl_fork模式来监听队列里的LIST有没有处理完成,没有就等待,有就继续处理,目前是打算这样设计,请问哪种模式会更好些

    第一步的创建子进程,用到的是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} ";
                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数组就可以让主进程等候所有进程完结之后再结束了

  • 相关阅读:
    Java UDP通信简单实现
    为什么要阅读——兼分享《首先,打破一切常规》[中译文]:世界顶级管理者的成功秘诀/(美)马库斯&#183;白金汉,(美)柯特&#183;科夫曼 著
    怎样提高团队管理能力9
    POJ2777 Count Color 线段树区间更新
    Swift和Objective-C混合编程——Swift调用OC
    LINK : fatal error LNK1123: 转换到 COFF 期间失败: 文件无效或损坏
    ZZUOJ-1195-OS Job Scheduling(郑州大学第七届ACM大学生程序设计竞赛E题)
    CentOS出错You don&#39;t have permission to access on this server
    string 和 vector 初探
    ICMP报文类型
  • 原文地址:https://www.cnblogs.com/liliuguang/p/12610377.html
Copyright © 2011-2022 走看看