小默

lighttpd - 1 - watcher 创建并监控 workers

http://bbs.chinaunix.net/viewthread.php?tid=1251434
==================
lighttpd 采用 多进程 的工作模式,watcher 创建 workers 并且监控 workers 的退出。

watcher 循环创建 worker, 子进程 被创建后跳出循环做自己的工作。
当创建够 子进程 后,父进程 调用 wait() 等待有 子进程退出。
当父进程wait()中收到信号 SIGHUP,通知进程组的所有成员。
当服务器被关闭,父进程kill所有子进程,做清理工作,退出循环。
==================
版本: 1.4.27
<server.c>
=================
/// watcher 创建并监控 workers 工作
#ifdef HAVE_FORK
    /* start watcher and workers */
    num_childs = srv->srvconf.max_worker;   // num_childs,需要创建的 worker 数量
    if (num_childs > 0) {
        int child = 0;      // child 是一个 flag, 为0是watcher(父进程),为1是worker(子进程)
        while (!child && !srv_shutdown && !graceful_shutdown) {     // 如果是父进程,且服务器没有被关闭
            if (num_childs > 0) { // num_childs>0, fork()创建子进程
                switch (fork()) {
                case -1:
                    return -1;
                case 0:     // 子进程,置child为1。退出循环。
                    child = 1;
                    break;
                default:    // 父进程,孩子数减1
                    num_childs--;
                    break;
                }
            } else {    // num_childs=0, 子进程已经创建完了,父进程wait()等待有子进程退出
                int status;

                if (-1 != wait(&status)) {  // 有子进程退出,num_childs++
                    /**
                     * one of our workers went away
                     */
                    num_childs++;
                } else {    // wait 返回错误 (-1)
                    switch (errno) {
                    case EINTR:     // wait()被中断打断
                        /**
                         * if we receive a SIGHUP we have to close our logs ourself as we don't
                         * have the mainloop who can help us here
                         */
                        if (handle_sig_hup) {   // 收到 SIGHUP, 关闭日志,通知进程组的所有进程
                            handle_sig_hup = 0;

                            log_error_cycle(srv);

                            /**
                             * forward to all procs in the process-group
                             *
                             * we also send it ourself
                             */
                            if (!forwarded_sig_hup) {
                                forwarded_sig_hup = 1;
                                kill(0, SIGHUP);    // pid=0 通知进程组所有成员
                            }
                        }
                        break;
                    default:
                        break;
                    }
                }
            }
        }

        /**
         * for the parent this is the exit-point
         */
         /// 服务器被关闭。通知进程组所有成员
         /// 父进程只在这时才退出循环
        if (!child) {
            /**
             * kill all children too
             */
            if (graceful_shutdown) {
                kill(0, SIGINT);
            } else if (srv_shutdown) {
                kill(0, SIGTERM);
            }

            // 清理工作
            log_error_close(srv);
            network_close(srv);
            connections_free(srv);
            plugins_free(srv);
            server_free(srv);
            return 0;
        }
    }
#endif

posted on 2010-08-17 00:28 小默 阅读(473) 评论(0)  编辑 收藏 引用 所属分类: Network


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


导航

统计

留言簿(13)

随笔分类(287)

随笔档案(289)

漏洞

搜索

积分与排名

最新评论

阅读排行榜