2016-11-06 83 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。