Linux system call, linux System Call Function
What is system call?
The Linux kernel has a set of built-in functions used to implement various system functions, which are called system calls. You can call a system call in an application to implement certain system functions. From a certain perspective, system calls are very similar to common function calls. The difference is that system calls are provided by the core of the operating system and run in the core State. Common function calls are provided by function libraries or users and run in the user State.
The system calls the application request to the kernel, calls the corresponding kernel function to complete the required processing, and returns the processing result to the application. System calling is an interface for user programs to interact with the kernel. Through system calls, you can easily and quickly implement some system functions.
In my personal understanding, if we compare the kernel to a class, system calling is a public interface for external applications to call.
Common Linux System Call process management related fork to create a new process
Getpid
Exit to terminate the process
_ Exit terminate the process immediately
Execve run executable files
Wait waits for the sub-process to end
Waitpid waits for the end of the specified sub-process
File read/write operations open File
Creat create a new file
Close file descriptor
Read a file
Write a file
Forkfork is called to replicate a process. When a process calls it, two processes are almost identical, and we get a new process.
In Linux, there is only one way to create a new process, that is, the fork we are introducing.
Other library functions, such as system (), seem to be capable of creating new processes. If you can look at their source code, you will understand that they actually call fork internally. This includes running the application under the command line. The new process is also created by calling fork by shell. One of the wonders of fork calling is that it is called only once, but can return twice. It may have three different return values:
1. In the parent process, fork returns the ID of the newly created sub-process;
2. In the sub-process, fork returns 0;
3. If an error occurs, fork returns a negative value;
Here, some readers may ask: if the sub-process after fork is almost the same as the parent process, and the only way to generate a new process in the system is fork, isn't all processes in the system identical? What should we do when we want to execute a new application?
Don't worry. exec will talk about this issue later. The execution process of _ exit, exit_exit, and exit is as follows:
It can be seen that the _ exit () function has the simplest function: directly stop the process, clear its memory space, and destroy its various data structures in the kernel; exit () the functions are encapsulated based on these and several processes are added before execution and exit.
The biggest difference between them 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, is the "clear I/O buffer" item in the figure.
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 that the file has been written, because it does not meet the specific conditions, they are only saved in the buffer, then we use _ exit () if a function is used to directly shut down the process, data in the buffer will be lost. If you want to ensure data integrity, you must use the exit () function.
Instance comparison
Exit. c
#include<stdlib.h>main(){printf("output begin\n");printf("content in buffer");exit(0);}
gcc exit.c -o exit./exit
Output
Output begin
Content in buffer
_ Exit. c
#include<unistd.h>main(){printf("output begin\n");printf("content in buffer");_exit(0);}
gcc _exit.c -o _exit1./_exit
Output
Output begin
Getpid
Obtain the ID of the current process. Process ID, which uniquely identifies a process
One or more processes can be combined to form a process group ),
One or more process groups can be combined to form a session ).
In this way, we have the ability to perform batch operations on processes, such as sending signals to a process group to send signals to each process in the group.
Waitpid and wait
Before explaining the calls of these two systems, first understand the process-related knowledge.
After a process calls exit, it does not disappear immediately, but leaves a data structure called Zombie. Among the five States of a Linux Process, a zombie process is a very special one. It has abandoned almost all the memory space, no executable code, and cannot be scheduled, only one location is retained in the process list, and information such as the exit status of the process is recorded for collection by other processes. In addition, zombie processes no longer occupy any memory space.
We have learned that the system calls exit. Its function is to exit a process, but it is only limited to converting a normal process into a zombie process and cannot be completely destroyed.
Waitpid call and wait call are used to collect information left by the zombie process and completely disappear the process.
Once a process calls wait, it immediately blocks itself. wait automatically analyzes whether a sub-process of the current process has exited. If it finds such a sub-process that has become a zombie, wait will collect information about this sub-process and destroy it completely and return it. If such a sub-process is not found, wait will be blocked until one appears.
Exec is called by the exec system. In fact, there is no exec () function in Linux. exec refers to a group of six functions in total, which are:
#include <unistd.h>int execl(const char *path, const char *arg, ...);int execlp(const char *file, const char *arg, ...);int execle(const char *path, const char *arg, ..., char *const envp[]);int execv(const char *path, char *const argv[]);int execvp(const char *file, char *const argv[]);int execve(const char *path, char *const argv[], char *const envp[]);
Among them, only execve is a real system call, and others are packaged library functions on this basis.
The role of exec is to find the executable file based on the specified file name and use it to replace the content of the calling process. In other words, it is to execute an executable file within the calling process. The executable file can be either a binary file or any script file that can be executed in Linux.
Unlike in general, functions in the exec function family are not returned after successful execution, because the entity of the calling process, including the code segment, data segment, and stack, has been replaced by new content, only some superficial information such as the process ID remains unchanged, which is quite similar to the "golden shell" in the "Plan ". It looks like an old shell, but it has injected a new soul.
Only when the call fails will they return a-1, which will be executed from the original program's call point.
Now we should understand how a new program is executed in Linux. Every time a process thinks that it cannot make any contribution to the system or the user, it can give full play to the last point, call any exec to regenerate itself with a new look; or, more commonly, if a process wants to execute another program, it can fork a new process, then call any exec, which looks like a new process is generated by executing the application.
In fact, the second scenario is so widely used that Linux has made special optimizations for it. We already know that, fork will copy all the content of the calling process to the newly generated child process, which consumes a lot of time. If fork is finished, we will call exec immediately, these hard-to-copy items will be immediately erased, which seems very uneconomical, so people have designed a technology called "copy-on-write, so that the fork does not copy the content of the parent process immediately after the end, but is copied only when the fork is actually practical, so that if the next statement is exec, it will not be useless, this improves efficiency.
Linux system call
This should not be the case. File Read locks and write locks should be mutually exclusive. This prevents data loss when multiple programs or users open the same file and write the same file at the same time. This is also a synchronization mechanism in linux, just like a mutex lock.
How can I differentiate functions in c library when shell commands are called in linux?
First, the command should be different from the other two, because the command can be directly typed on the shell and press enter to execute, and neither the system call nor the library function can;
Second, both Linux and C library functions are in the form of functions, that is, they are in the form of "func (args)", but the system call is
The service interfaces provided by the system kernel. The C library functions are essentially different from the common functions you write, but only in the C standard library. in Linux, glibc is the C library. On the surface, the two are not very well differentiated. However, you can distinguish them from the header files they need to include. C library functions are like printf in <stdio. in h>, std is the abbreviation of standard. Therefore, in <stdxxx. h> the functions in are basically C-library functions, such as ssize_t read (int fd, void * buf, size_t count). Many such system calls are included in <unistd. in h>, unistd indicates UNIX Standard, which can be distinguished.
Please feel free to contact me at any time if you have any questions :-)
References: personal experience