2016-11-06 81 views

回答

5

进程ID:子进程和父进程

所有正在运行的程序都有唯一的进程ID。 process ID, 非负整数是进程的唯一标识符,即 总是唯一。但是,进程ID被重用。

当一个进程终止它的ID变得可用于重用。某些 系统会延迟重用,以便新创建的进程不会与旧版进程相混淆 。

某些ID是“保留的”,意思是它们正在被 系统进程使用,例如调度程序进程。另一个示例是始终占用PID 1的 初始化过程。根据系统 ,ID可能会被主动保留。

运行命令

> ps -eaf | head -n 5 
UID  PID PPID C STIME TTY   TIME CMD 
root   1  0 0 11:49 ?  00:00:02 /sbin/init splash 
root   2  0 0 11:49 ?  00:00:00 [kthreadd] 
root   3  2 0 11:49 ?  00:00:00 [ksoftirqd/0] 
root   5  2 0 11:49 ?  00:00:00 [kworker/0:0H] 

> pidof init 
1 

将允许您独立验证这一点。

在C,我们可以使用下面的函数来获得该主叫 进程的进程ID和调用进程的父进程ID,

#include <unistd.h> 

pid_t getpid(void); 
pid_t getppid(void); 

进程可以创建其他进程。创建的进程被称为 “子进程”,我们将创建它们的进程称为 “父进程”。

用fork()

要创建我们使用系统调用 fork()

#include <unistd.h> 

pid_t fork(void); 

该函数被调用一次,由父进程子进程创建一个新的进程,但它返回 两次。子进程中的返回值为0,并且父进程中的返回值 是新子进程的ID。

一个进程可以有多个子进程,但没有系统 呼吁建立过程中得到所有的子进程的ID,所以 父观察子进程的返回值,可以使用 这些标识符来管理它们。

一个进程只能有一个父进程,总是可以调用getppid获得 。

孩子是复制母公司,它得到复制父母的 数据空间,堆和栈的。他们做没有分享这些部分的 内存!

我们将编译并执行下面的代码片段,看看如何 这个工程,

#include <stdio.h> 
#include <sys/types.h> 
#include <unistd.h> 
#include <sys/syscall.h> 

int main(void) { 
    int var = 42; // This variable is created on the stack 
    pid_t pid; 

    // Two processes are created here 
    //     v~~~~~~~~~~| 
    if ((pid = fork()) < 0) { 
     perror("Fork failed"); 
    } else if (pid == 0) { // <- Both processes continue executing here 
     // This variable gets copied 
     var++; 

     printf("This is the child process:\n" 
       "\t my pid=%d\n" 
       "\t parent pid=%d\n" 
       "\t var=%d\n", getpid(), getppid(), var); 

    } else { 
     printf("This is the parent process:\n" 
       "\t my pid=%d\n" 
       "\t child pid=%d\n" 
       "\t var=%d\n", getpid(), pid, var); 

    } 


    return 0; 
} 

,有没有保证 哪个进程到达我们会看到,当我们执行程序先执行。他们甚至可以同时操作 ,有效地交错输出。

$ # Standard compilation 
$ gcc -std=c99 -Wall fork_example1.c -o fork_example1 
$ # Sometimes the child executes in its entirety first 
$ ./fork_example1 
This is the child process: 
    my pid=26485 
    parent pid=26484 
    var=43 
This is the parent process: 
    my pid=26484 
    child pid=26485 
    var=42 
$ # and sometimes the parent executes in its entirety first 
$ ./fork_example1 
This is the parent process: 
    my pid=26461 
    child pid=26462 
    var=42 
This is the child process: 
    my pid=26462 
    parent pid=26461 
    var=43 
$ # At times the two might interleave 
$ ./fork_example1 
This is the parent process: 
    my pid=26455 
This is the child process: 
    my pid=26456 
    parent pid=26455 
    var=43 
    child pid=26456 
    var=42 

PID代表进程IDPPID代表 父进程ID

进程标识0保留给内核使用,所以 0不可能是子进程标识。

许多系统不执行这些 内存段的完整副本,而是仅当任一过程 执行写创建一个副本。最初,共享区域被 内核标记为“只读”,并且只要进程尝试修改这些区域,内核就会奖励每个进程自己的内存副本。

标准输出是缓冲所以它不是一个完美的例子。

+0

当这些是你的过程时,很容易知道哪个过程是孩子,但我认为问题是关于确定pid的其他过程。 – interjay

+2

我相信你的第二个例子实际上告诉你,如果你在一个进程的主线程中,而不是如果你在主进程中(不管这意味着什么)。 – interjay

1

使用getpid()和getppid()函数来获取进程ID和父进程ID。

相关问题