Inherit from parent process
- Process Eligibility (live (real)/active (Effective)/saved (saved) user number (UIDs) and group number (Gids))
- Environment (environment)
- Stack
- The memory
- opens a descriptor for the file (note that the location of the corresponding file is also shared with the file by the parent-child process)
- when executed (CLOSE-ON-EXEC) flag (Translator Note: The CLOSE-ON-EXEC flag is available through FNCTL () For file descriptor settings, POSIX.1 requires that all directory streams must be closed when the EXEC function is called. In more detail, see Advanced Programming for UNIX Environments W. R. Stevens, 1993, Yu Jinyuan (hereinafter referred to as Advanced programming), section 3.13 and 8.9)
- signal (signal) control sets the
- semaphore (semaphor e)
- Nice value (translator Note: The nice value is set by the Nice function, which represents the priority of the process, the smaller the value, the higher the priority)
- process scheduling category (Scheduler Class) ( Note: Process scheduling category refers to the process in the system is dispatched when the category, different categories have different priorities, according to the process scheduling category and nice value, the process scheduler can calculate the global priority of each process (global process prority), high priority process priority execution)
- Process Group number
- conversation period ID (session ID) (Advanced Programming: Session ID of the session to which the process belongs, a conversation period consisting of one or more process groups, in more detail refer to "Advanced Programming" section 9.5)
- when The front working directory
- root directory (the root directory is not necessarily the operating system's "/", it can be changed by the chroot function)
- file mode to create the mask (file mode creation mask (umask)) (Advanced programming : Create a default screen word for a new file)
- resource limit
- control terminal
- all mutexes, read-write locks, and condition variables (colleagues consider multithreaded environments)
The child process is unique
- Process number
- Different parent process Number (Translator Note: The parent process number of the child process is different from the parent process number, the parent process number can be obtained by the GETPPID function)
- Copy of your own file descriptor and directory stream (translator Note: The directory stream is created by the Opendir function, because it is read sequentially, and is called "Directory Flow")
- The child process does not inherit the process of the parent process, body (text), data and other locked memory (locks) (Translator Note: Locked memory refers to locked virtual memory pages, locked, the kernel is not allowed to swap out when necessary (page out), detailed instructions see the GNU C Library Reference Manual Edition 2.2, 1999, 3.4.2)
- System time in the TMS architecture (Translator Note: The TMS structure can be obtained by the Times function, which holds four data to record the time that the process uses the central processing Unit (cpu:central processing units), including: User Time, System time, total time of the user's child processes, Total time of each sub-process of the system)
- Resource Usage (resource utilizations) set to 0
- Block signal sets are initialized to an empty set (translator Note: The original text is ambiguous here, the translation is slightly modified according to the Fork Function manual page)
- Do not inherit timers created by the Timer_create function
- Do not inherit asynchronous inputs and outputs
- File locks are not inherited, for specific reasons see references.
Random Thoughts
- Assuming that fork occurs when there are multiple threads in the parent process , consider the following issues:
A child process inherits a copy of the entire address space so that the parent process inherits all the mutex, read-write locks, and condition state. If the parent process contains more than one thread, the child process will need to clean up the lock state if it is not immediately called exec after the fork returns. There is only one thread inside the child process, which is returned by the parent process call fork, and if the thread in the parent process holds the lock, the child process also occupies those locks, the problem is that the child processes also occupy those locks--but the child processes do not contain copies of the thread that holds the locks. So the child process has no way of knowing which locks it occupies and which locks to release. This can be avoided if the child process calls an EXEC function immediately after returning from the fork. In this case, the old address space is discarded, so the state of the lock does not matter.
Of course, without exec, you can also use Pthread_atfork, before calling fork, the thread gets all the locks in the process, frees the locks in the parent-child process after calling fork, so that the parent can regain and release the lock resources.
The
- Pthread interface also provides a process-wide shared mutex, which is required to set the mutex type to pthread_process_shared, because it is an inter-process share that requires mutex init, which uses the shared memory area to allocate the mutex amount. inter-process mutual exclusion , also recommend reading "Nginx Module development and Structure Analysis" the last chapter on the implementation of mutual exclusion lock, one is based on file locks, one is based on atomic operations & Signal volume.
-
record the inheritance and release of Locks
1, locks and processes, and files
A, when a process terminates, the locks it establishes are all released, (that is, process exits, file locks are automatically released)
B, Any time a descriptor is closed, the process is freed by any lock on the file that the descriptor can reference. (That is, close the file, file lock is automatically released)
Case One::
fd1 = open (pathname,....);
Read_lock (fd1,....);
Fd2 = DUP (FD1);
Close (FD2);//At this time, after close (FD2), the lock added on the FD1 is released.
Case Two::
fd1 = open (pathname,....);
Read_lock (fd1,....);
Fd2 = open (pathname,...);
Close (FD2);//At this time, after close (FD2), the lock added on the FD1 is released.
2, the child process generated by the fork does not inherit the lock set by the parent process. (File lock cannot be inherited)
This means that if a process gets a lock and then calls Fork, the child process is treated as another process for the lock acquired by the parent process, and for the any descriptor inherited from the parent process, the child process needs to call Fcntl to get its own lock.
(This is also the original intention of the lock, the role of a file lock is to prevent multiple processes to write a file or region at the same time, if the child process inherits the lock of the parent process, the parent can write the same file at the same time.) This is obviously wrong.
3, after exec executes, the new program can inherit the lock of the original execution program. (Exec file Lock is inherited)
executes exec, replacing the process entity of the original process with the process entity of the current process. The original process was killed (but the process ID is left PID)
What the parent-child process shares