每天看点英文文档:APUE第三版

Posted 看,未来

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了每天看点英文文档:APUE第三版相关的知识,希望对你有一定的参考价值。

1.6 Programs and Processes(程序与进程)

Program

A program is an executable file residing on disk in a directory. A program is read into memory and is executed by the kernel as a result of one of the seven exec functions.
We’ll cover these functions in Section 8.10.

程序是存放于磁盘目录中的一个可执行文件,当内核调用七个exec函数时,程序将hi被读取到内存中,并产生结果。
我们将会再第八章的第十小部分讲解这七个exec函数。


Processes and Process ID

An executing instance of a program is called a process, a term(术语) used on almost every page of this text. Some operating systems use the term task to refer to a program that is being executed.
The UNIX System guarantees that every process has a unique numeric identifier called the process ID. The process ID is always a non-negative integer.

进程是正在运行的程序接口,这个术语将几乎在本书的每一页中都出现,有的操作系统也用之来指代正在运行的程序。
Unix操作系统确保每个进程都有独一无二的非负整数的编码,称之为进程ID。

Example

The program in Figure 1.6 prints its process ID.

#include "apue.h"

int main(void){
	printf("hello world from process ID %ld\\n", (long)getpid());
	exit(0);
}
If we compile this program into the file a.out and execute it, we have
$ ./a.out
hello world from process ID 851
$ ./a.out
hello world from process ID 854

When this program runs, it calls the function getpid to obtain its process ID. As we shall see later(我们稍后会看到), getpid returns a pid_t data type. We don’t know its size; all we know is that the standards guarantee that it will fit in a long integer. Because we have to tell printf the size of each argument to be printed, we have to cast the value to the largest data type that it might use (in this case, a long integer). Although most process IDs will fit in an int, using a long promotes portability.

运行这个程序的时候,将会使用 getpid 函数来获取进程ID,我们稍后会看到,getpid 函数返回了一个pid_t 类型的数据。我们不知道它的大小,我们只知道它将适合一个长整数。因为我们必须告诉printf要打印的每个参数的大小,所以我们必须将该值转换为它可能使用的最大数据类型(在本例中为长整数)。尽管大多数进程ID都适合int,但使用long可以提高可移植性。


Process Control

There are three primary functions for process control: fork, exec, and waitpid. (The exec function has seven variants, but we often refer to them collectively as simply the exec function.)

有三个基本的进程控制函数:fork、exec和waitpip。exec函数有七种形态,但是我们一般统称其为exec族。

(此处省去一大段函数)

We call fork to create a new process, which is a copy of the caller. We say that the caller is the parent and that the newly created process is the child. Then fork returns the non-negative process ID of the new child process to the parent,and returns 0 to the child. Because fork creates a new process, we say that it is called once—by the parent — but returns twice—in the parent and in the child.

我们调用fork来创建一个新进程,它是调用者的副本。我们说调用方是父进程,新创建的进程是子进程。然后fork将新子进程的非负进程ID返回给父进程,并将0返回给子进程。因为fork创建了一个新进程,所以我们说它被父进程调用一次,但在父进程和子进程中返回两次。

In the child, we call execlp to execute the command that was read from the standard input. This replaces the child process with the new program file. The combination of fork followed by exec is called spawning a new process on some operating systems. In the UNIX System, the two parts are separated into individual functions.

在子进程中,我们调用execlp来执行从标准输入读取的命令。这将用新的程序文件替换子进程。fork和exec的组合称为在某些操作系统上生成新进程。在UNIX系统中,这两个部分被分成单独的函数。

Because the child calls execlp to execute the new program file, the parent wants to wait for the child to terminate. This is done by calling waitpid, specifying which process to wait for: the pid argument, which is the process ID of the child. The waitpid function also returns the termination status of the child — the status variable — but in this simple program, we don’t do anything with this value. We could examine it to determine how the child terminated.

因为子进程调用execlp来执行新的程序文件,如果父进程要等待子进程终止,需要通过调用waitpid来完成,指定要等待哪个进程:pid参数,它是子进程的进程ID。waitpid函数还返回子级的终止状态(status变量),我们通过可以检查它以确定子进程是如何终止的。

The most fundamental limitation of this program is that we can’t pass arguments to the command we execute. We can’t, for example, specify the name of a directory to list. We can execute ls only on the working directory. To allow arguments would require that we parse the input line, separating the arguments by some convention, probably spaces or tabs, and then pass each argument as a separate parameter to the execlp function.

这个程序最基本的限制是我们不能将参数传递给我们执行的命令。例如,我们不能指定要列出的目录的名称。我们只能在工作目录上执行ls。要允许参数,我们需要解析输入行,通过某种约定(可能是空格或制表符)分隔参数,然后将每个参数作为单独的参数传递给execlp函数。


Threads and Thread IDs(线程和线程ID)

Usually,aprocess has only one thread of control — one set of machine instructions executing at a time. Some problems are easier to solve when more than one thread of control can operate on different parts of the problem. Additionally, multiple threads of control can exploit(利用) the parallelism(并行) possible on multiprocessor systems.

通常,一个进程只有一个控制线程——一次执行一组机器指令。当多个控制线程可以对问题的不同部分进行操作时,有些问题更容易解决。此外,多个控制线程可以利用多处理器系统上可能的并行性。

All threads within a process share the same address space, file descriptors, stacks, and process-related attributes. Each thread executes on its own stack, although any thread can access the stacks of other threads in the same process. Because they can access the same memory, the threads need to synchronize access to shared data among themselves to avoid inconsistencies.

进程中的所有线程共享相同的地址空间、文件描述符、堆栈和与进程相关的属性。每个线程在自己的堆栈上执行,尽管任何线程都可以访问同一进程中其他线程的堆栈。因为它们可以访问相同的内存,所以线程之间需要同步对共享数据的访问,以避免不一致。

Like processes, threads are identified by IDs. Thread IDs, however, are local to a process. A thread ID from one process has no meaning in another process. We use thread IDs to refer to specific threads as we manipulate the threads within a process.

Functions to control threads parallel those used to control processes. Because threads were added to the UNIX System long after the process model was established, however, the thread model and the process model have some complicated interactions, as we shall see in Chapter 12.

与进程一样,线程由ID标识。但是,线程ID是进程的本地ID。一个进程的线程ID在另一个进程中没有意义。在处理进程中的线程时,我们使用线程ID来引用特定的线程。

用于控制线程的函数与用于控制进程的函数并行。由于线程是在进程模型建立很久之后添加到UNIX系统的,因此,线程模型和进程模型有一些复杂的交互作用,我们将在第12章中看到。

以上是关于每天看点英文文档:APUE第三版的主要内容,如果未能解决你的问题,请参考以下文章

每天看点英文文档:APUE第三版

每天看点英文文档:APUE第三版

每天看点英文文档:APUE第三版

每天看点英文文档:APUE第三版

每天看点英文文档:APUE第三版

每天看点英文文档:APUE第三版