init进程_处理子进程终止1

1.init启动过程
linux内核启动–>用户空间中启动init进程–>启动其他系统进程–>init变成守护进程
内核空间:–>start_kernel
–>rest_init :kernel_thread(kernel_init, NULL, CLONE_FS | CLONE_SIGHAND);
–>kernel_init
–>run_init_process(execute_command)
用户空间:–>init进程
–>启动用户空间其他进程

2.处理子进程终止
处理子进程终止

分析init.c源代码:
位置:Z:\项目\system\core\init

int main(int argc, char **argv)
{
...
queue_builtin_action(signal_init_action, "signal_init"); //跳转2.1解析
...
//init进程的事件处理循环
 for(;;) {
        ...
 /*当有signal_recv_fd的时候,注册struct pollfd结构体,监听的文件描述符为signal_recv_fd,监听的事件为POLLIN*/
         if (!signal_fd_init && get_signal_fd() > 0) {
            ufds[fd_count].fd = get_signal_fd();
            ufds[fd_count].events = POLLIN;
            ufds[fd_count].revents = 0;
            fd_count++;
            signal_fd_init = 1;
        }
        ...
	    //开始监听
        nr = poll(ufds, fd_count, timeout);
        if (nr <= 0)
            continue;
		//某个文件套接字有动静进行分析处理
        for (i = 0; i < fd_count; i++) {
            if (ufds[i].revents & POLLIN) {//判断是哪一个套接字发生了POLLIN事件
                if (ufds[i].fd == get_property_set_fd())
                    handle_property_set_fd();
                else if (ufds[i].fd == get_keychord_fd())
                    handle_keychord();
                else if (ufds[i].fd == get_signal_fd())
                    handle_signal(); //处理子进程终止
            }
        }
    }

    return 0;
}

2.1
queue_builtin_action(int (*func)(int nargs,char **args), char *name)
是以name形成action,挂在action_list上;以func和name组成command,挂在action的commands上。然后加入到action_queue的队尾。

之后执行signal_init_action–>signal_init

static int signal_fd = -1;        //子进程套接字
static int signal_recv_fd = -1;   //init进程套接字

static void sigchld_handler(int s)
{
    write(signal_fd, &s, 1);     //往signal_fd的文件中写1,signal_recv_fd会发现
}

void signal_init(void)
{
    int s[2];//套接字的两个fd         

	//注册SIGCHLD信号,当发生SIGCHLD信号时候调用sigchld_handler函数
    struct sigaction act;
    memset(&act, 0, sizeof(act));
    //sigchld_handler函数是往文件描述符为 signal_fd的套接字写1
    act.sa_handler = sigchld_handler;
    act.sa_flags = SA_NOCLDSTOP;
    sigaction(SIGCHLD, &act, 0);

    /* 创建一对已经连接的通信套接字signal_fd和signal_recv_fd,当发生SIGCHLD信号的时候,sigchld_handle函数把signal_fd设置为1,此时通过套接字对,signal_recv_fd也被设置为1。main函数中的poll会监视signal_recv_fd的值,当发现为1的时候,init进程就会调用handle_signal() */
    if (socketpair(AF_UNIX, SOCK_STREAM, 0, s) == 0) {
        signal_fd = s[0];
        signal_recv_fd = s[1];
        fcntl(s[0], F_SETFD, FD_CLOEXEC);  //fcntl是设置文件描述符属性的函数
        fcntl(s[0], F_SETFL, O_NONBLOCK);
        fcntl(s[1], F_SETFD, FD_CLOEXEC);
        fcntl(s[1], F_SETFL, O_NONBLOCK);
    }

    handle_signal(); //不明白handle_signal()出现在这
}

分析handle_signal见init进程_处理子进程终止2

学习辛苦啦,现在不妨换换思路,瞧点文学东西,

如果你喜欢,聊历史,思哲学,品诗集,赏国学。

那就关注公众号:二校五叔

这个是博主的文学公众号啦^ _ ^

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值