`
Jonathan樊
  • 浏览: 77024 次
  • 性别: Icon_minigender_2
  • 来自: 上海
社区版块
存档分类
最新评论

Linux下PHP多进程实现(1)

阅读更多

什么是一个进程?

进程这个概念是针对系统而不是针对用户的,对用户来说,他面对的概念是程序。当用户敲入命令执行一个程序的时候,对系统而言,它将启动一个进程。但和程序不同的是,在这个进程中,系统可能需要再启动一个或多个进程来完成独立的多个任务。多进程编程的主要内容包括进程控制和进程间通信,在了解这些之前,我们先要简单知道进程的结构。

 

Linux下进程的结构

Linux下一个进程在内存里有三部分的数据:"代码段"、"堆栈段"和"数据段"。"代码段",顾名思义,就是存放了程序代码的数据,假如机器中有数个进程运行相同的一个程序,那么它们就可以使用相同的代码段。"堆栈段"存放的就是子程序的返回地址、子程序的参数以及程序的局部变量。而数据段则存放程序的全局变量,常数以及动态数据分配的数据空间。

 

Linux下进程控制

在传统的Unix环境下,有两个基本的操作用于创建和修改进程:函数fork( )用来创建一个新的进程,该进程几乎是当前进程的一个完全拷贝;函数族exec( )用来启动另外的进程以取代当前运行的进程。

fork()之后exec()之前两个进程用的是相同的物理空间(内存区),子进程的代码段、数据段、堆栈都是指向父进程的物理空间,也就是说,两者的虚拟空间不同,但其对应的物理空间是同一个。当父子进程中有更改相应段的行为发生时,再为子进程相应的段分配物理空间,如果不是因为exec,内核会给子进程的数据段、堆栈段分配相应的物理空间(至此两者有各自的进程空间,互不影响),而代码段继续共享父进程的物理空间(两者的代码完全相同)。而如果是因为exec,由于两者执行的代码不同,子进程的代码段也会分配单独的物理空间。

 

fork()函数一次调用却有两个返回值。对于父进程,fork()函数返回了子程序的进程号,而对于子程序,fork()函数则返回零。如果函数调用不成功,则返回-1。

 

在进程运行时,如果子进程先退出,它不会从进程列表里清除。而要发一个SIGCHLD(或SIGCLD)信号给父进程,父进程确认后子进程才会退出。在等待父进程确认期间,子进程处于“zombie”状态。所以我们就需要使用wait()函数。如果调用wait()函数时已经有一个处于“zombie”状态的子进程,那么函数立即返回的同时该子进程从内存中清除出去;否则,主进程会处于阻塞状态,直到子进程退出后才继续执行,而无法进行其他任务。还有一个办法可以解决办法就是拦截处理信号SIGCHLD(或SIGCLD)。子进程在终止时会给父进程发SIGCHLD信号,该信号的默认处理动作是忽略,父进程可以自定义SIGCHLD信号的处理函数,这样父进程只需专心处理自己的工作,不必关心子进程了,子进程终止时会通知父进程,父进程在信号处理函数中调用wait清理子进程即可。

如果父进程不关心子进程什么时候结束,那么可以用signal(SIGCHLD, SIG_IGN) 通知内核,自己对子进程的结束不感兴趣,那么子进程结束后,内核会回收, 并不再给父进程发送信号。

 

在Linux系统中,子进程的正常/异常终止都会给父进程发送SIGCHLD的信号,当父进程接收到子进程(第一个)信号进行wait()或waitpid()时,会屏蔽掉下一个的SIGCHLD信号,实际的效果就是在信号处理函数返回前不会重入。

那么当父进程在执行信号处理函数时,又有子进程(第二个)退出,那么信号会被阻塞并等待处理,假如(第三个)又来了,那么它是被抛弃的,后续的都会抛弃。。。

所以说信号是阻塞但不排队的。

如果子进程可能会同时退出,那么父进程需要这样来处理以防止僵尸进程的出现:

while( (childpid = waitpid(-1, NULL, WNOHANG)) > 0)

{

 ...

}

这样,即使出现子进程同时退出的情况,SIGCHLD的信号被抛弃也没有关系。waitpid会收集所有当前已终止(实际就是处于僵尸状态)的子进程,直到没有这样的进程状态需要收集(返回0)。

 

一个简单的例子如下:

<?php
/**
 * 多进程实现
 * User: Eleanor
 * Date: 2014/12/23
 * Time: 18:49
 */
declare(ticks = 1);
define('ProcessNum',5);
function signalHandler($signal){
    if($signal==SIGCHLD){
        echo 'SIGCHLD received.'."\n";
    }
    //$pid = pcntl_wait($status, WNOHANG);
    $pid = pcntl_waitpid(-1, $status, WNOHANG);
    echo "{$pid} exit; \n";
}
pcntl_signal(SIGCHLD,"signalHandler",true);
//pcntl_signal_dispatch();
for($i=0;$i<ProcessNum;$i++){
    $pid=pcntl_fork();
    if($pid==-1){
        exit("create child process failed \n");
    }elseif($pid==0){
        echo "I am the child process. my pid is:".posix_getpid().'and my parent pid is:'.posix_getppid()."\n";
        exit ;
    }
}
while(1){
    echo "Waiting for child process to finish... \n";
    sleep(1);
}

 

 

<?php
/**
 * 多进程实现
 * User: Eleanor
 * Date: 2014/12/23
 * Time: 18:49
 */
declare(ticks = 1);
define('ProcessNum',10);
function signalHandler($signal){
    if($signal==SIGCHLD){
        echo 'SIGCHLD received.'."\n";
    }
}
pcntl_signal(SIGCHLD,"signalHandler");
//pcntl_signal_dispatch();

for($i=0;$i<ProcessNum;$i++){
    $pid=pcntl_fork();
    if($pid==-1){
        exit("create child process failed \n");
    }elseif($pid==0){
        echo "I am the child process. my pid is:".posix_getpid().'and my parent pid is:'.posix_getppid()."\n";
        exit ;
    }
}

while(($pid = pcntl_wait($status)) > 0)
{
    echo "{$pid} exit; \n";
}

 

 执行结果如下:


 

 

  • 大小: 228.3 KB
  • 大小: 230 KB
1
1
分享到:
评论

相关推荐

    PHP多进程编程实例

    在Linux系统下实现PHP多进程编程是这篇文章的主要内容。文章通过实例的方式向读者展示了如何使用PHP的pcntl扩展来创建和管理多进程。由于PHP是一种主要用于Web开发的编程语言,它本身并不擅长处理多进程任务,所以在...

    Linux下实现PHP多进程的方法分享

    以下是一个简单的PHP多进程示例代码: ```php &lt;?php declare(ticks=1); // 设置ticks计数器,用于处理信号 $bWaitFlag = FALSE; // 是否等待进程结束 $intNum = 10; // 进程总数 $pids = array(); // 进程PID数组 ...

    linux守护进程

    ### Linux守护进程详解 ...通过以上的讲解,我们可以看到守护进程在Linux系统中的重要作用以及其实现的基本步骤。无论是简单的定时任务还是复杂的网络服务,守护进程都能够提供稳定可靠的后台服务支持。

    基于PHP的多进程定时任务框架设计源码

    taskPHP是一个基于PHP的多进程定时任务框架,采用多进程技术实现任务的高效分配和执行。该项目支持多进程和多线程模式,推荐安装pthreads扩展以获得更佳性能,同时兼容Linux和Windows操作系统。项目包含39个文件,...

    linux下实现负载均衡

    在Linux环境下实现负载均衡,通常会使用到诸如LVS(Linux Virtual Server)这样的技术,它是一种高可用性集群解决方案,可以有效地将流量分发到多个服务器,提高系统的处理能力和响应速度,同时保证服务的连续性和...

    taskPHP基于php开发的定时计划任务框架,多进程实现任务的分配和运行

    这个框架的一大亮点是其多进程实现,能够有效地分配和运行任务,提高任务执行效率。 ### 1. 多进程技术 在`taskPHP`中,多进程功能使得框架可以同时处理多个任务,提高了任务执行的速度和并发性。通过创建子进程,...

    PHP多进程简单实例小结

    本文将深入探讨PHP多进程的原理、实现方法以及在使用过程中的注意事项。 首先,PHP多进程的核心在于`pcntl`模块,它是PHP的一个扩展,提供了进程控制的功能。在编译PHP时,需要通过`--enable-pcntl`选项开启这个...

    PHP多进程编程实例详解

    PHP多进程编程是指在PHP中创建和操作多个进程的编程技术,它允许开发者在脚本中并行地执行多个任务。多进程编程在需要进行大量网络操作或计算密集型任务时非常有用,尤其是在多核处理器的系统中,通过并行处理可以...

    基于PHP多进程内存共享的定时计划任务框架设计源码

    该框架利用PHP的多进程和内存共享特性,实现了任务的高效分配与执行,并支持跨平台运行于Linux和Windows系统。以其良好的伸缩性、扩展性和稳定性,被多家公司采用,并鼓励开源爱好者共同参与贡献。

    PHP常驻内存的多进程任务管理器Composer包

    PHP常驻内存的多进程任务管理器Composer包。以进程管理为出发点,同时也支持为每个进程设置定时执行功能,您可以用它来完成需要重复运行的任务(如订单超时自动取消,短信邮件异步推送,队列/消费者/频道订阅者等等),...

    PHP多进程编程总结(推荐)

    多进程编程的一个常见用途是实现并发处理,例如在Web服务器中处理大量请求或在后台执行耗时的操作。通过创建子进程,每个子进程可以并行执行任务,提高程序的执行效率。然而,需要注意的是,多进程间的通信和同步...

    LINUX 服务器端PHP客户端 TCP 聊天程序

    4. **多路复用**:如果需要同时处理多个客户端,可以使用`select()`、`poll()`或`epoll`等机制实现多线程或多进程并发处理。 **PHP客户端**通常由用户在浏览器或者命令行中运行,它通过socket API与服务器建立连接...

    php中实现进程锁与多进程的方法

    PHP中实现进程锁与多进程的方法涵盖了进程锁的基本概念、在单进程和多进程中的使用,以及在Yii2框架中的具体实现和如何杀死进程。下面将详细阐述这些知识点。 首先,进程锁的主要作用是防止程序的重复执行,尤其...

    解决Linux下php-fpm进程过多导致内存耗尽问题

    总结来说,解决Linux下php-fpm进程过多导致内存耗尽的问题,主要步骤包括: 1. 使用`free -m`和`top`命令监控内存使用情况。 2. 通过`ps`命令找出内存消耗大的进程,特别是php-fpm进程。 3. 修改php-fpm配置,降低`...

    php5.2.8.tar.gz(php安装包for linux)

    《PHP 5.2.8在Linux环境下的安装与配置详解》 PHP(Hypertext Preprocessor)是一种广泛使用的开源脚本语言,尤其适合于Web开发。本文将详细阐述如何在Linux环境中安装PHP 5.2.8版本,以及与Apache服务器的集成,...

    PHP常驻内存多进程任务管理器,支持定时任务

    "PHP常驻内存多进程任务管理器,支持定时任务" 是一个利用PHP实现的高效能工具,它扩展了PHP在后台处理和任务调度的能力。这个系统设计的核心在于保持PHP进程常驻内存,以提高性能和响应速度,并通过多进程管理和...

    Linux系统搭建PHP开发环境

    在Linux系统中,尤其是Ubuntu,搭建PHP开发环境是开发者日常工作中常见的任务。LNNP(Linux、Nginx、MySQL、PHP)是一个流行的Web服务架构,用于高效地运行动态内容和静态内容。在这个环境中,Linux作为操作系统,...

    PHP CLI模式下的多进程应用分析

    在分析PHP CLI(Command Line Interface,命令行接口)模式下的多进程应用时,首先要明确的是PHP在命令行模式下与Web服务器环境下的使用场景和限制有所不同。在Web环境下,PHP通常用于处理HTTP请求,其运行周期短暂...

Global site tag (gtag.js) - Google Analytics