workerman运行分析--主进程流程

基本上,workerman使用多进程的方式、使用libevent事件监听网络连接,达到高并发。它与nginx的进程模型相似,连接的处理,是由子进程完成的,主进程主要的工作是:

  1.  监听端口,生成子进程要共享的server_socket

  2. 监听传递给自己的信号,如reload restart等,并进行相应处理

  3. 监听子进程退出的事件,并及启动新的子进程补上

master进程(master进程会先建立好需要listen的socket)--------fork生成子进程workers,继承socket(此时workers子进程们都继承了父进程master的所有属性,当然也包括已经建立好的socket,当然不是同一个socket,只是每个进程的这个socket会监控在同一个ip地址与端口的网络事件,这个在网络协议里面是允许的)------当一个连接进入,产生惊群现象。

workerman中对惊群事件没有特殊处理,只是简单地忽略掉它了,这个对性能影响也很小,对业务更没有影响。

使用多个子进程,就可以充分利用多个cpu,并显著提高并发连接和处理能力。


一,主进程的挂起原理

主进程监听好端口,生成子进程后,自身就处于挂起状态,只处理两件事件:监听信号、监听是否有子进程退出,实现代码见Worker::monitorWorkers方法

while(1) {
    pcntl_signal_dispatch();
    // 挂起进程,直到有子进程退出或者被信号打断
    $status = 0;
    $pid = pcntl_wait($status, WUNTRACED);
            // 如果有信号到来,尝试触发信号处理函数
    pcntl_signal_dispatch();
    
    if($pid > 0){
        //如果有子进程退出 则尝试fork一个子进程
    }else{
        //说明收到了信号
    }
}

让进程挂起的关键就是调用pcntl_wait函数,它会一直等待、直到收到信号或有子进程退出时返回,返回值就是退出的子进程pid

pcntl_wait第二个参数可设为:

WNOHANG   没有子进程退出时,立即返回,显然它不能挂起进程

WUNTRACED  子进程已经退出时,立即返回,这才是实现进程挂起的关键。

正因为主进程一直是挂起状态,所以它并不消耗系统资源。

我们调用stop|restart|reload|status|kill命令,其实是给已经运行的主进程发送相关信号。

你可能感兴趣的:(workerman运行分析--主进程流程)