2016-11-06 6 views
0

プロセスがpidを使用して別のプロセスの子/孫であるかどうかをどのように識別しますか?プロセスが親子かどうかを知る方法

+0

['man 2 getpid'](https://linux.die.net/man/2/getpid) – chrk

+0

' ps -eal | 'PID'と' PPID'(そして 'man ps'も同様に)を検査します。 – alk

答えて

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で

我々は、プロセスが他のプロセスを作成することができます

#include <unistd.h> 

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

、 呼び出したプロセスのプロセスIDと呼び出し元プロセスの親プロセスIDを取得するには、以下の機能を使用することができます。作成されたプロセスは 「子プロセス」と呼ばれ、作成されたプロセスは 「親プロセス」となります。

我々は関数は親プロセスによって、一度呼び出され fork()

#include <unistd.h> 

pid_t fork(void); 

システムコールを使用して子プロセスを作成するにはフォーク()

を使用して新しいプロセスを作成する

が、それは を返します。二度。子プロセスの戻り値は0で、親プロセスの戻り値 の値は新しい子のプロセスIDです。

プロセスは複数の子プロセスを持つことができますが、そのすべての子のプロセスIDを取得するためのプロセスのためのシステム コールが存在しないので、 親は子プロセスの戻り値を観測し、使用することができますこれらの識別子を管理するためには 。

プロセスには、親プロセスが1つしかない場合があります。これは、 で、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 

親プロセスIDを表しプロセスIDPPIDの略 PID。

プロセスID 0はカーネルで使用するために予約されているため、 は0を子のプロセスIDにすることはできません。

多くのシステムでは、これら メモリセグメントの完全なコピーを実行し、代わりにプロセス いずれかが書き込みを行った場合のみコピーが作成されません。当初、共有領域は カーネルによって "読み取り専用"としてマークされ、プロセスがこれらの領域を変更しようとするたびに、カーネル賞はそれぞれ独自のメモリコピーを処理します。

標準出力はバッファリングです。これは完全な例ではありません。

+0

これらがあなたのプロセスであるときにどのプロセスが子供であるのかを知ることは簡単ですが、他のプロセスの – interjay

+2

そして、あなたの2番目の例は、あなたがプロセスのメインスレッドにいるかどうかを実際に教えてくれるものと信じています。 – interjay

1

getpid()およびgetppid()関数を使用して、プロセスIDと親プロセスIDを取得します。

関連する問題