signal by epoll .etc

Interruption of System Calls and Library Functions by Signal Handlers

If a signal handler is invoked while a system call or library function call is blocked, then either:
*
the call is automatically restarted after the signal handler returns; or
*
the call fails with the error EINTR.
Which of these two behaviors occurs depends on the interface and whether or not the signal handler was established using the SA_RESTART flag (see sigaction(2)). The details vary across UNIX systems; below, the details for Linux.

If a blocked call to one of the following interfaces is interrupted by a signal handler, then the call will be automatically restarted after the signal handler returns if the SA_RESTART flag was used; otherwise the call will fail with the error EINTR:

*
read(2), readv(2), write(2), writev(2), and ioctl(2) calls on “slow” devices. A “slow” device is one where the I/O call may block for an indefinite time, for example, a terminal, pipe, or socket. (A disk is not a slow device according to this definition.) If an I/O call on a slow device has already transferred some data by the time it is interrupted by a signal handler, then the call will return a success status (normally, the number of bytes transferred).
*
open(2), if it can block (e.g., when opening a FIFO; see fifo(7)).
*
wait(2), wait3(2), wait4(2), waitid(2), and waitpid(2).
*
Socket interfaces: accept(2), connect(2), recv(2), recvfrom(2), recvmsg(2), send(2), sendto(2), and sendmsg(2), unless a timeout has been set on the socket (see below).
*
File locking interfaces: flock(2) and fcntl(2) F_SETLKW.
*
POSIX message queue interfaces: mq_receive(3), mq_timedreceive(3), mq_send(3), and mq_timedsend(3).
*
futex(2) FUTEX_WAIT (since Linux 2.6.22; beforehand, always failed with EINTR).
*
POSIX semaphore interfaces: sem_wait(3) and sem_timedwait(3) (since Linux 2.6.22; beforehand, always failed with EINTR).
The following interfaces are never restarted after being interrupted by a signal handler, regardless of the use of SA_RESTART; they always fail with the error EINTR when interrupted by a signal handler:

*
Socket interfaces, when a timeout has been set on the socket using setsockopt(2): accept(2), recv(2), recvfrom(2), and recvmsg(2), if a receive timeout (SO_RCVTIMEO) has been set; connect(2), send(2), sendto(2), and sendmsg(2), if a send timeout (SO_SNDTIMEO) has been set.
*
Interfaces used to wait for signals: pause(2), sigsuspend(2), sigtimedwait(2), and sigwaitinfo(2).
*
File descriptor multiplexing interfaces: epoll_wait(2), epoll_pwait(2), poll(2), ppoll(2), select(2), and pselect(2).
*
System V IPC interfaces: msgrcv(2), msgsnd(2), semop(2), and semtimedop(2).
*
Sleep interfaces: clock_nanosleep(2), nanosleep(2), and usleep(3).
*
read(2) from an inotify(7) file descriptor.
*
io_getevents(2).
The sleep(3) function is also never restarted if interrupted by a handler, but gives a success return: the number of seconds remaining to sleep.

Interruption of System Calls and Library Functions by Stop Signals

On Linux, even in the absence of signal handlers, certain blocking interfaces can fail with the error EINTR after the process is stopped by one of the stop signals and then resumed via SIGCONT. This behavior is not sanctioned by POSIX.1, and doesn’t occur on other systems.
The Linux interfaces that display this behavior are:

*
Socket interfaces, when a timeout has been set on the socket using setsockopt(2): accept(2), recv(2), recvfrom(2), and recvmsg(2), if a receive timeout (SO_RCVTIMEO) has been set; connect(2), send(2), sendto(2), and sendmsg(2), if a send timeout (SO_SNDTIMEO) has been set.
*
epoll_wait(2), epoll_pwait(2).
*
semop(2), semtimedop(2).
*
sigtimedwait(2), sigwaitinfo(2).
*
read(2) from an inotify(7) file descriptor.
*
Linux 2.6.21 and earlier: futex(2) FUTEX_WAIT, sem_timedwait(3), sem_wait(3).
*
Linux 2.6.8 and earlier: msgrcv(2), msgsnd(2).
*
Linux 2.4 and earlier: nanosleep(2).

fork()

fork之后,从 fork 处开始父子进程并行执行,公有变量的值也在 fork 处被复制(当时的值),则父子进程分别使用各自的复本(而非共享)

共生成多少个子进程?
简查了一下 fork() 的知识,它调用一次,返回两次,进入子进程并返回一次,然后退到父进程再返回一次,子进程中返回值为 0,父进程中返回的是子进程的进程号。
这就是一个二项树,二项树结点的计算公式为 2^n – 1,当 n = 5 时,结果为 31。