zoukankan      html  css  js  c++  java
  • php多进程编程

    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 $options = 0])
    • pcntl_waitpid(int $pid , int &$status[,int $options = 0]) $status是作为一下函数的参数
    • pcntl_wifexited(int $status) 检查子进程状态代码是否代表正常退出,
    • pcntl_wexistatus(int $status) 返回一个中断的子进程返回代码,仅在正常中断才有效
    • pcntl_wifsignaled(int $status) 检查子进程是否由某个未捕获的信号退出的。是返回true,否返回false
    • pcntl_wtermsig(int $status)返回导致子进程中断的信号,当pcntl_wifsignaled返回true时有效
    <?php
     echo "主进程
    ";
     $pid = pcntl_fork();
     //父进程和子进程都会执行这些代码
     if($pid == -1 ){
         //创建子进程失败会返回-1
         throw new Exception ('fork error on Task object');
     }else if($pid){
         //创建成功会父进程会得到子进程的pid
         echo "等待子进程执行";
         pcntl_wait($status);//等待子进程中断
         echo "子进程执行状态:";
         echo "是否正常退出:",pcntl_wifexited($status),"
    ";
         echo "子进程返回的代码:",pcntl_wexitstatus($status),"
    ";//仅在pcntl_wifexited返回true时生效,只能是int,输出123
         echo "子进程是否是由于某个未捕获的信号退出的:",pcntl_wifsignaled($status),"
    ";//如果是kill -9|-15 杀死的进程返回true
         echo "导致子进程中断的信号:",pcntl_wtermsig($status),"
    "; 输出 9 | 15
         var_dump($status);
     }else{
         //创建成功子进程会得到pid=0
         sleep(2);
         echo "子进程执行完毕
    ";
             exit(123)
     }
    • pcntl_alarm(int $seconds):为进程设置一个alarn闹钟信号
    • pcntl_signal(int $signo, callback $handler [, bool $restart_syscalls = true ] )为指定的信号安装一个新的信号处理器
    • pcntl_signal_get_handler(int $signo) 获取指定信号的处理函数
    <?php
     
    echo "设置3秒之后发送闹钟信号
    ";
    pcntl_alarm(3);
     
    function dealSigalarm(){
        echo "收到信号 SIGALRM 
    退出程序。。。
    ";
        exit();
    }
     
    echo "安装信号处理器
    ";
    pcntl_signal(SIGALRM,"dealSigalarm");//对于不能被阻塞、处理和忽略的信号,php为这些事件注册信号处理函数会产生一个致命错误 SIGSTOP,SIGKILL
    var_dump(pcntl_signal_get_handler(SIGUSR1));//输出dealSigalarm
    pcntl_signal(SIGUSR1,function(){
        echo "收到用户自定义信号
    ";
    });
    $i = 1;
    while(1){
        sleep(1);
        echo $i++,"
    ";
        echo "分发... 
    ";
        pcntl_signal_dispatch();
    };
    • pcntl_getpriority( int $pid = getmypid() [, int $process_identifier = PRIO_PROCESS ])获取进程的优先级
    • pcntl_setpriority( int $priority [ , int $pid = getmypid() [, int $process_identifier = PRIO_PROCESS]])设置进程的优先级
    • getmypid() 获取当前php进程的pid
    • posix_getpid() 获取当前进程的pid
    <?php
     /**
     * php进程的优先级
     */
     
     for($i = 1;$i<=5;$i++){
         $pid = pcntl_fork();
         if($pid == -1){
             throw new Exception("fork error on task object");
         }else if ($pid){
             pcntl_wait($status);
         }else{
             $end_time = time()+3;
             $k = 0;
             while(time()<=$end_time){
                 $k++;
             }
             $pid = getmypid();
             echo "当前进程id:".$pid,"优先级:",pcntl_getpriority($pid);
             pcntl_setpriority($i);
             echo "修改之后的优先级为:",pcntl_getpriority(),"
    ";
             echo "执行了进程{$i} {$k}次
    ";
             exit();
         }
     }
     
  • 相关阅读:
    【C++】资源管理
    【Shell脚本】逐行处理文本文件
    【算法题】rand5()产生rand7()
    【Shell脚本】字符串处理
    Apple iOS产品硬件参数. 不及格的程序员
    与iPhone的差距! 不及格的程序员
    iPhone游戏 Mr.Karoshi"过劳死"通关. 不及格的程序员
    XCode V4 发布了, 苹果的却是个变态. 不及格的程序员
    何时readonly 字段不是 readonly 的?结果出呼你想象!!! 不及格的程序员
    object file format unrecognized, invalid, or unsuitable Command 不及格的程序员
  • 原文地址:https://www.cnblogs.com/jint-php7/p/12201205.html
Copyright © 2011-2022 走看看