Reprinted on http://www.360doc.com/content/12/0504/15/9400799_208611794.shtml
# Include <stdlib. h>
Void exit (INT status );
It is not as hard to understand as fork. From the exit name, we can see that this system call is used to terminate a process. No matter where the program is located, as long as the exit system call is executed, the process will stop all the remaining operations, clear various data structures including the PCB, and terminate the operation of the process. See the following program:
/* Exit_test1.c */
# Include <stdlib. h>
Main ()
{
Printf ("this process will exit! \ N ");
Exit (0 );
Printf ("Never be displayed! \ N ");
}
Compile and run:
$ GCC exit_test1.c-O exit_test1
$./Exit_test1
This process will exit!
We can see that the program does not print "Never be displayed! \ N ", because before that, when exit (0) is executed, the process has been terminated.
The exit system calls the status parameter with an integer type. We can use this parameter to pass the status at the end of the process. For example, if the process ends normally or unexpectedly, in general, 0 indicates that the process has not ended normally. Other values indicate that an error has occurred and the process has ended abnormally. In actual programming, we can use the wait system to call and receive the return values of sub-processes, so as to handle different situations. We will introduce the wait details in the future.
Exit and _ exit
As a system call, _ exit and exit are a pair of twins.
At this time, anyone who knows C language and is clear-headed will say that _ exit and exit are no different, but we also need to talk about the difference between them, which is mainly reflected in their function libraries.
. The prototype of _ exit in the Linux function library is:
# Include <unistd. h>
Void _ exit (INT status );
The exit () function is defined in stdlib. h, while _ exit () is defined in unistd. h, from the name, stdlib. H seems better than unistd. h. What is the difference between them?
The _ exit () function has the simplest function: directly stop the process, clear the memory space it uses, and destroy various data structures in the kernel; exit () some functions are encapsulated based on these elements and several processes are added before execution and exit. This is also the reason why some people think that exit is no longer a pure system call.
The biggest difference between the exit () function and the _ exit () function is that the exit () function checks the file opening before calling the exit system, and writes the content in the File Buffer back to the file, that is, "Clear the I/O buffer ".
In the standard library of Linux, there is a set of functions called "Advanced I/O". The well-known printf (), fopen (), fread (), and fwrite () are listed in this column, they are also referred to as "buffer I/O (buffered I/O)", which is characterized by a buffer in the memory corresponding to each opened file. Each time a file is read, several more records will be read, so that the next time you read the file, you can directly read it from the memory buffer. Each time you write the file, it is only written into the buffer zone in the memory, when a certain number of conditions are met, or a specific character, such as the line break \ n and the file Terminator EOF, is met, and then the content in the buffer is written to the file at one time, this greatly increases the speed of reading and writing files, but it also brings us a little trouble in programming. If there is some data, we think the file has been written,
In fact, because they do not meet specific conditions, they are only stored in the buffer zone. In this case, we use the _ exit () function to directly close the process, and the data in the buffer zone will be lost.Otherwise, if you want to guarantee the number
Data integrity, you must use the exit () function.
See the following routine
/* Exit2.c */
# Include <stdlib. h>
Main ()
{
Printf ("output begin \ n ");
Printf ("content in buffer ");
Exit (0 );
}
Compile and run:
$ GCC exit2.c-O exit2
$./Exit2
Output begin
Content in buffer
/* _ Exit1.c */
# Include <unistd. h>
Main ()
{
Printf ("output begin \ n ");
Printf ("content in buffer"); // note, do not add the \ n carriage return line break in this place. Otherwise, the output will be displayed.
_ Exit (0 );
}
Compile and run:
$ GCC _ exit1.c-O _ exit1
$./_ Exit1
Output begin
Return, exit (), _ exit ()
1. Return can only return the current function. It is often used to obtain the return value of the function. Only return in the main function can exit the program. In the subroutine, return can only return the next-level calling program.
2. The process ends when the exit () and _ exit () functions are called. The difference between them is that they do different cleanup work at the end. Exit () closes all opened files before exiting the program, clears the standard input and output buffer, and finally executes the callback function registered by atexit () (use the return effect and exit () in main () ). While _ exit () does not close open files, does not clear the buffer, and does not execute the callback function registered by atexit (), which is processed by the kernel.
3. Therefore,In the fork () sub-process, it is best not to use exit () to exit, because the cleaning work generated by the sub-process calling exit () may affect the parent process.
For example:
# Include <stdio. h>
# Include <unistd. h>
# Include <stdlib. h>
VoidGood ()
{
Printf ("Yes \ n ");
}
VoidMain ()
{
Atexit (good );
Printf ("Hello \ n ");
Exit (exit_success );
}
Output:
Hello
Yes
# Include <stdio. h>
# Include <unistd. h>
# Include <stdlib. h>
VoidGood ()
{
Printf ("Yes \ n ");
}
VoidMain ()
{
Atexit (good );
Printf ("Hello \ n ");
_ Exit (exit_success );
}
Output:
Hello
Linux source code
# Define_ Nr_exit1
# DEFINE _ nR _ exit _ nr_exit/* from the File Include/asm-i386/unistd. H */
"_ NR _" is the prefix for each system call in the Linux source code. Note that there are two underscores before the first exit and only one underline before the second exit.
Linux core also provides some C language function libraries that pack and expand system calls because these libraries are closely related to system calls, these functions are also called system-call. # Define indicates that the two systems in the kernel call _ exit and exit are the same, but the C library functions _ exit () and exit () are different after encapsulation.
The exit () function is defined in stdlib. h, and the _ exit () function is defined in unistd. h;
The exit () function has the simplest function: directly stop the process, clear the memory space it uses, and destroy various data structures in the kernel; exit () the function is encapsulated on the basis of this-several processes are added before execution and exit. This is also the reason why some people think that exit is no longer a pure system call.
The biggest difference between the exit () function and the _ exit () function is that the exit () function checks the file opening before calling the exit system, and writes the content in the File Buffer back to the file, this is the so-called "clear I/O buffer ".
There are many differences between 'exit () 'and' _ exit () 'when using 'fork ()', especially 'vfork.
The basic difference between 'exit () 'and' _ exit () 'is that the user-mode constructs) clean-up and user-defined purge programs are called. The user-defined purge program is defined by the atexit function and can be defined multiple times, and executed in reverse order). Correspondingly, the last function only performs kernel cleanup for the process.
In the sub-process Branch created by 'fork () ', it is incorrect to use 'exit ()' normally, this is because it causes standard input and output (Note: stdio: Standard ).
The buffer of input output is cleared twice, and the temporary file is unexpectedly deleted. (Note: the temporary file is created in the temporary directory of the system by the tmpfile function, the file name is randomly generated by the system ). In the C ++ program, the situation is worse, because the static state target (static
Objects destructor can be incorrectly executed. (In some special cases, such as Daemon, their parent processes need to call '_ exit ()' instead of the Child processes. The basic rule for most cases is, 'exit () 'It is called only once after each entry to the 'main' function .)
In the sub-process Branch created by 'vfork () ', the use of 'exit ()' is more dangerous because it affects the status of the parent process.
Fork: The child process has the data segment, heap, and stack copies of the parent process. The parent process and the child process share the body segment. However, many implementations do not completely copy the data and stack segments of the parent process, but adopt copy-on-write (copy-on-write), and the kernel marks it as read-only, (typical webpage-based Virtual Memory) the kernel copies the page physically only when the parent process or child process modifies these areas.
Vfork: Because after vfork, it is often followed by an exec to execute a new program, it will not use the original address space, therefore, the child process of vfork runs in the space of the parent process before calling exec or exit, which is highly efficient for Webpage-based virtual storage. In addition, the child process of vfork is always executed with the parent process first, but the child process cannot depend on the execution of the parent process or lead to a deadlock.
Exit (0): depending on the implementation, it is generally to refresh the I/O buffer and close all the I/O standard streams (apue says, but the result of my verification in Linux should not be closed). Generally, the current I/O library functions are not in trouble to close the I/O Stream.
_ Exit (0): Do not refresh the I/O Buffer
Standard I/O Library:
The standard I/O Library is cache-based. If the standard output is connected to the terminal device, it is a row buffer; otherwise, it is a full buffer. The row buffer is refreshed only when a line break is received, and the full buffer is full when the buffer is full or after the program exits after the exit is executed, it is refreshed in the execution buffer.