Like fork.
Fork () is simple. You can constantly generate new processes so that they can process different parts of the problem in parallel. Of course, it would be easiest if these processes do not communicate with each other during running and where they just do their own thing.
In Unix systems, the only way to create a new process is to call the fork system. The process called fork is called the parent process, and the newly created process is called the child process. Syntax format of system call:
PID = fork ();
When the fork is returned from the system call, the two processes have the same user-level context except the PID of the returned value. In the sub-process, the PID value is zero. The process 0 created by the core internal and external locations at system startup is the only process created without the system call fork.
The core is to call fork to complete the following operations:
Assign an empty entry to the new process in the progress table.
Assign a unique process ID (PID) to the sub-process ).
Make a logical copy of the context of the parent process. Some parts of a process, such as the body area, may be shared by several processes. Therefore, the core sometimes only needs to increase the number of references in a specific area, instead of copying the region to a new physical memory zone.
Increase the number of file tables and index node tables associated with the process.
Returns the process number of the child process to the parent process, and returns zero to the child process.
It is very important to understand the implementation of the System Call fork, because the sub-process starts its execution sequence as it drops from the sky.
The following is the fork algorithm called by the system. The core is confident that there are enough resources to successfully complete the fork. If the resource does not meet the requirements, the system fails to call fork. If the resource meets the requirements, the core finds an empty entry in the Process Table and starts to construct the context of the sub-process.
Algorithm: fork
Input: None
Output: PID of the parent process as a child process
The sub-process is 0.
{
Check available core resources
Take an idle table entry and a unique PID Number.
Check that the user does not run too many processes
Set the sub-process status to "CREATE ".
Copy the data in the parent process's table to the child table.
Index node of the current directory and reference of the changed root directory (if possible) plus 1
Add 1 to the reference number of open files in the file table
Copy the context of the parent process in the memory
In the system-level context of a sub-process, medium pressure is applied to the virtual system-level context layer.
/* The virtual context layer contains sub-Processes
* Identify your own data and schedule sub-Processes
* Start from here
*/
If (the process being executed is a parent process ){
Set the sub-process status to "ready ".
Return (pid of the sub-process) // from the system to the user
}
Else {
Initialize the timing Zone
Return 0;
}
}
Let's take a look at the example below. This program indicates the shared access to files after fork is called by the system. When a user calls this program, there should be two parameters: one is the existing file name and the other is the new file name to be created. This process opens an existing file, creates a new file, and then, if there is no error, it calls fork to create a child process. Sub-processes can inherit the files of the parent process by using the same file descriptor (that is, files opened and created by the parent process ).
Of course, the parent process and child process must independently call the rdwrt function and execute a loop, that is, read a byte from the source file and write a byte to the target file. When the system calls read to the end of a file, rdwrt returns immediately.
# Include
Intfdrd, fdwt;
Charc;
Main (INT argc, char * argv [])
{
If (argc! = 3 ){
Exit (1 );
}
If (fdrd = open (argv [1], o_rdonly) =-1 ){
Exit (1 );
}
If (fdwt = creat (argv [2], 0666) =-1 ){
Exit (1 );
}
Fork ();
// The two processes run the same code
Rdwrt ();
Exit (0 );
}
Rdwrt ()
{
For (;;){
If (read (fdrd, & C, 1 )! = 1 ){
Return;
}
Write (fdwt, & C, 1 );
}
}
In this example, the file descriptors of both processes point to the same file table item. These two processes will never read or write to the same file offset, because the core will increase the file offset after each read and write call. Although the two processes seem to have copied the source files twice, the content of the target file depends on the order of the two processes scheduled by the core because they share the task. If the core schedules two processes in this way: enable them to execute their system calls alternately, or even enable them to execute each pair of Read and Write calls alternately, the content of the target file is exactly the same as that of the source file. But consider this situation: the two processes are about to read two consecutive characters in the source file "AB ". Assume that the parent process reads the character "A". At this time, the core performs context switching before writing the parent process to execute the child process. If a child process reads the character "B" and writes it to the target file before the parent process is scheduled, the target file will no longer contain the string "AB ", it contains "ba. The core does not guarantee the relative speed of process execution.
Let's take a look at another example:
# Include
Charstring [] = "Hello, world ";
Main ()
{
Intcount, I;
Intto_par [2], to_chil [2]; // pipeline to parent and child Processes
Charbuf [2, 256];
Pipe (to_par );
Pipe (to_chil );
If (Fork () = 0 ){
// The sub-process is executed here
Close (0); // close the old standard input.
DUP (to_child [0]); // copy the read of the MPs queue to the standard input.
Close (1); // close the old standard output
DUP (to_par [1]); // copy the write of the pipeline to the standard output
Close (to_par [1]); // close unnecessary pipeline Descriptors
Close (to_chil [0]);
Close (to_par [0]);
Close (to_chil [1]);
For (;;){
If (COUNT = read (0, Buf, sizeof (BUF) = 0)
Exit ();
Write (1, Buf, count );
}
}
// The parent process is executed here
Close (1); // reset the Standard Input and Output
DUP (to_chil [1]);
Close (0 );
DUP (to_par [0]);
Close (to_chil [1]);
Close (to_par [0]);
Close (to_chil [0]);
Close (to_par [1]);
For (I = 0; I
Previous Article: install or upgrade ora 1.0 RedHat 9.0 8.0 7.x as 2.1 as3.0 and other releases through grub
Next article: lumaqq Startup Script