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

来源:互联网 发布:对比度调整算法 编辑:程序博客网 时间:2024/05/21 20:22

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

0 0
原创粉丝点击