The signal processing flow of Android init process is introduced in detail

Signal processing flow of Android init process

In Android, when a process exits (exit ()), it sends a sigchld signal to its parent process. After the parent process receives the signal, it will release the system resources allocated to the child process; And the parent process needs to call wait () or waitpid () to wait for the child process to finish. If the parent process does not do this kind of processing, and the parent process does not call signal (sigcld, sig_ign) to show that the processing of sigcld is ignored during initialization, the child process will always maintain the current exit state and will not exit completely. Such a sub process cannot be scheduled. All it does is occupy a position in the process list and save the PID, termination status, CPU usage time and other information of the process; We call this process "zombie" process, that is, zombie process.

In Linux, the purpose of setting up a zombie process is to maintain some information of the child process for subsequent query by the parent process. In particular, if a parent process terminates, the parent processes of all its zombie child processes will be set as init processes (PID is 1), and the init process is responsible for recycling these zombie processes (init processes will wait() / waitpid() them and clear their information in the process list).

Since zombie processes will still occupy a position in the process list, the maximum number of processes supported by Linux is limited; Beyond this threshold, we cannot create a process. Therefore, it is necessary to clean up those zombie processes to ensure the normal operation of the system.

Next, we analyze how the init process processes sigchld signals.

In init.cpp, we use signal_ handler_ Init() to initialize sigchld signal processing:

We initialize the signal through the sigaction () function. In the act parameter, the signal processing function is specified: sigchld_ handler(); If a signal arrives, the function will be called for processing; At the same time, in the parameter act, we also set SA_ The nocldstop flag indicates that the sigchld signal is accepted only when the child process terminates.

In Linux, signal is a kind of soft interrupt, so the arrival of signal will terminate the operation being processed by the current process. Therefore, we should not call some non reentrant functions in the registered signal processing functions. Moreover, Linux will not queue signals. No matter how many signals are received during the processing of a signal, the kernel will only send another signal to the process after the current signal processing is completed; So there is the possibility of signal loss. In order to avoid signal loss, the more efficient and faster the operation of our registered signal processing function should be.

When we process sigchld signals, the parent process will wait for a long time. To solve this problem, the above signal initialization code creates a pair of unnamed and associated local sockets for inter thread communication. The registered signal processing function is sigchld_ handler():

When a signal arrives, as long as the data is written to the socket, the process is very fast. At this time, the signal processing is transferred to the response of the socket; This will not affect the processing of the next signal. At the same time, a do... While loop is nested around the write() function. The loop condition is that write() has an error and the current error number is Eintr (Eintr: this call is interrupted by a signal), that is, when the current write() has an error due to the arrival of an interrupt, the operation will be executed again; In other cases, the write () function executes only once. After initializing the signal processing, reap will be called_ any_ outstanding_ Children() handles the process exit before this:

wait_ for_ one_ Process () mainly calls waitpid () to wait for the child process to finish. When the service represented by the process needs to be restarted, it will do some setting and cleaning work. Finally, through epoll_ Ctl() to epoll_ FD registers the local socket and monitors whether it is readable; And registered the epoll event handler:

Let's take zygote process exit as an example to see the specific flow of sigchld signal processing. The zygote process is declared as a service in init.rc and created by the init process. When the zygote process exits, a sigchld signal is sent to the init process. The previous code has completed the initialization of the signal, so sigchld will be called when the signal arrives_ Handler () function processing, its processing is to write a data directly through the socket and return it immediately; At this time, the processing of sigchld is transferred to the response of socket event. We passed epoll_ CTL registers the local socket and monitors whether it is readable; At this time, due to the previous write () call, the socket has data readable, and the registered handle will be called at this time_ Signal() function:

It will save the data of socket into buf and call reap_ any_ outstanding_ The children() function handles the exit of the child process and the restart of the service:

The main points of processing in this function are as follows:

If the service represented by this sub process needs to be restarted, SVC will be added to the service_ The restarting flag.

When we introduced the init process initialization process earlier, we analyzed that when the init process finishes processing, it will enter a cycle, incarnate as a daemon, and process services such as signal, property and keychord:

Where it calls restart in a loop_ Processes () to restart the service_ List list with all SVCS_ Services with the restarting flag (which is set in the wait_for_one_process())

The service will eventually be called_ The start () function restarts an exiting service. service_ The processing process of start () has been analyzed when introducing the processing flow of init process, so it will not be repeated here.

Thank you for reading, hope to help you, thank you for your support to this site!

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>