linux系统调用简介
To understand system calls, first one needs to understand the difference between kernel mode and user mode of a CPU. Every modern operating system supports these two modes.
要了解系统调用,首先需要了解CPU的内核模式和用户模式之间的区别。 每个现代操作系统都支持这两种模式。
Modes supported by the operating system
操作系统支持的模式
内核模式 (Kernel Mode)
When CPU is in kernel mode, the code being executed can access any memory address and any hardware resource.
当CPU处于内核模式时 ,正在执行的代码可以访问任何内存地址和任何硬件资源。
Hence kernel mode is a very privileged and powerful mode.
因此,内核模式是一种非常特权和强大的模式。
If a program crashes in kernel mode, the entire system will be halted.
如果程序在内核模式下崩溃,则整个系统将被暂停。
用户模式 (User Mode)
When CPU is in user mode, the programs don't have direct access to memory and hardware resources.
当CPU处于用户模式时 ,程序无法直接访问内存和硬件资源。
In user mode, if any program crashes, only that particular program is halted.
在用户模式下,如果任何程序崩溃,则仅停止该特定程序。
That means the system will be in a safe state even if a program in user mode crashes.
这意味着即使用户模式下的程序崩溃,系统也将处于安全状态。
Hence, most programs in an OS run in user mode.
因此,操作系统中的大多数程序都在用户模式下运行。
系统调用 (System Call)
When a program in user mode requires access to RAM or a hardware resource, it must ask the kernel to provide access to that resource. This is done via something called a system call.
当处于用户模式下的程序需要访问RAM或硬件资源时,它必须要求内核提供对该资源的访问。 这是通过称为系统调用的方式完成的 。
When a program makes a system call, the mode is switched from user mode to kernel mode. This is called a context switch.
当程序进行系统调用时,模式将从用户模式切换到内核模式。 这称为上下文切换 。
Then the kernel provides the resource which the program requested. After that, another context switch happens which results in change of mode from kernel mode back to user mode.
然后内核提供程序请求的资源。 此后,发生另一个上下文切换,这导致模式从内核模式更改回用户模式。
Generally, system calls are made by the user level programs in the following situations:
通常,在以下情况下,系统调用是由用户级程序进行的:
Creating, opening, closing and deleting files in the file system.
在文件系统中创建,打开,关闭和删除文件。
Creating and managing new processes.
创建和管理新流程。
Creating a connection in the network, sending and receiving packets.
在网络中创建连接,发送和接收数据包。
Requesting access to a hardware device, like a mouse or a printer.
请求访问硬件设备,例如鼠标或打印机。
In a typical UNIX system, there are around 300 system calls. Some of them which are important ones in this context, are described below.
在典型的UNIX系统中,大约有300个系统调用。 下面介绍其中一些在此方面很重要的内容。
叉子() (Fork())
The fork()
system call is used to create processes. When a process (a program in execution) makes a fork()
call, an exact copy of the process is created. Now there are two processes, one being the parent process and the other being the child process.
fork()
系统调用用于创建进程。 当某个进程(正在执行的程序)进行fork()
调用时,将创建该进程的精确副本。 现在有两个进程,一个是父进程,另一个是子进程。
The process which called the fork()
call is the parent process and the process which is created newly is called the child process. The child process will be exactly the same as the parent. Note that the process state of the parent i.e., the address space, variables, open files etc. is copied into the child process. This means that the parent and child processes have identical but physically different address spaces. The change of values in parent process doesn't affect the child and vice versa is true too.
称为fork()
调用的进程是父进程,而新创建的进程称为子进程。 子进程将与父进程完全相同。 注意,父进程的状态,即地址空间,变量,打开的文件等被复制到子进程中。 这意味着父进程和子进程具有相同但物理上不同的地址空间。 在父进程中更改值不会影响子进程,反之亦然。
Both processes start execution from the next line of code i.e., the line after the fork()
call. Let's look at an example:
这两个过程都从下一行代码(即fork()
调用之后的那一行fork()
开始执行。 让我们看一个例子:
// example.c
#include
void main()
{int val; val = fork(); // line Aprintf("%d", val); // line B
}
When the above example code is executed, when line A is executed, a child process is created. Now both processes start execution from line B. To differentiate between the child process and the parent process, we need to look at the value returned by the fork()
call.
当执行上述示例代码时,在执行A行时 ,将创建一个子进程。 现在,两个进程都从B行开始执行。 为了区分子进程和父进程,我们需要查看fork()
调用返回的值。
The difference is that, in the parent process, fork() returns a value which represents the process ID of the child process. But in the child process, fork()
returns the value 0.
不同之处在于,在父进程中,fork()返回一个表示子进程的进程ID的值。 但是在子进程中, fork()
返回值0。
This means that according to the above program, the output of parent process will be the process ID of the child process and the output of the child process will be 0.
这意味着根据上述程序,父进程的输出将是子进程的进程ID ,子进程的输出将为0。
执行() (Exec())
The exec()
system call is also used to create processes. But there is one big difference between fork()
and exec()
calls. The fork()
call creates a new process while preserving the parent process. But, an exec()
call replaces the address space, text segment, data segment etc. of the current process with the new process.
exec()
系统调用也用于创建进程。 但是fork()
和exec()
调用之间有一个很大的区别。 fork()
调用会在保留父进程的同时创建一个新进程。 但是, exec()
调用将新进程替换当前进程的地址空间,文本段,数据段等。
It means, after an exec()
call, only the new process exists. The process which made the system call, wouldn't exist.
这意味着,在exec()
之后,仅存在新进程。 进行系统调用的过程将不存在。
There are many flavors of exec()
in UNIX, one being exec1()
which is shown below as an example:
UNIX中有多种exec()
,其中一种是exec1()
,如下所示:
// example2.c
#include
void main()
{execl("/bin/ls", "ls", 0); // line Aprintf("This text won't be printed unless an error occurs in exec().");
}
As shown above, the first parameter to the execl() function is the address of the program which needs to be executed, in this case, the address of the ls utility in UNIX. Then it is followed by the name of the program which is ls in this case and followed by optional arguments. Then the list should be terminated by a NULL pointer (0).
如上所示,execl()函数的第一个参数是需要执行的程序的地址,在这种情况下,是UNIX中ls实用程序的地址。 然后,其后是程序的名称(在这种情况下为ls) ,后跟可选参数。 然后,该列表应以NULL指针(0)终止。
When the above example is executed, at line A, the ls program is called and executed and the current process is halted. Hence the printf()
function is never called since the process has already been halted. The only exception to this is that, if the execl() function causes an error, then the printf()
function is executed.
当执行上述示例时,在A行,将调用并执行ls程序,并暂停当前进程。 因此,由于该进程已经停止,因此永远不会调用printf()
函数。 唯一的例外是,如果execl()函数导致错误,则执行printf()
函数。
翻译自: https://www.studytonight.com/operating-system/system-calls
linux系统调用简介