プロセスが予想されるプロセスグループの一部ではないのはなぜですか?

プロセスが予想されるプロセスグループの一部ではないのはなぜですか?

私はLinuxのプロセス、プロセスグループ(およびセッション)間の関係について学びます。

次のプログラムをコンパイルしました...

#include <iostream>
#include <ctime>
#include <unistd.h>

int main( int argc, char* argv[] )
{
  char buf[128];
  time_t now;
  struct tm* tm_now;
  while ( true )
  {
    time( &now );
    tm_now = localtime( &now );
    strftime( buf, sizeof(buf), "%a, %d %b %Y %T %z", tm_now );
    std::cout << buf << std::endl;
    sleep(5);
  }
  return 0;
}

...a.out次のようにバックグラウンドプロセスとして実行します。

a.out &

このウェブサイト次のように教えてください...

各プロセスは、プロセスグループIDによって識別される一意のプロセスグループのメンバーです。 (プロセスが作成されると、親プロセスグループのメンバーになります。)通常、プロセスグループのプロセスグループIDは、プロセスグループの最初のメンバー(プロセスグループリーダーと呼ばれる)のプロセスIDと同じです。 。

私が読んだところによると、最初の文は括弧内の内容と衝突します。ユニークプロセスグループまたはプロセスグループのメンバーその親の

調べてみましたがps

ps xao pid,ppid,pgid,sid,command | grep "PGID\|a.out"
  PID  PPID  PGID   SID COMMAND
24714 23890 24714 23890 ./a.out

これは私のa.outプロセスがpid24714であり、親pidで作成され、23890プログラムグループの一部であることを示しています24714。まず、このpgidがpidと一致する理由を理解できません。

次に、親プロセスを調べてみました。

ps xao pid,ppid,pgid,sid,command | grep "PGID\|23890"
  PID  PPID  PGID   SID COMMAND
23890 11892 23890 23890 bash
24714 23890 24714 23890 ./a.out

私の親プロセスa.outは私にとって意味がありますbash。最初は「と思いました。bashのpidはpgidと一致します。これはプロセスグループリーダーだからです。おそらくbashが実行される「最初のタスク」であり、私はbashでプロセスを実行するので、これは意味があるかもしれません。a.outしかし、pgidも自分のpidと一致するので、この推論は意味がありません。

a.outなぜ'のpgidが'のpgidと等しくないのですかbash?この文章の私の理解に基づいて、これが私が期待したものです。

誰かがpidとpgidの関係を明確にすることはできますか?

ベストアンサー1

衝突はありません。デフォルトでは、プロセスは親である唯一のプロセスグループに属します。

$ cat pg.c
#include <stdio.h>
#include <unistd.h>
int main(void)
{
    fork();
    printf("pid=%d pgid=%d\n", getpid(), getpgrp());
}
$ make pg
cc     pg.c   -o pg
$ ./pg 
pid=12495 pgid=12495
pid=12496 pgid=12495
$ 

forkプロセスを親プロセス(12495)と子プロセス()に分割し、子プロセスは12496親プロセス()12495の一意のプロセスグループに属します。bash追加のシステムコールを実行するため、これとは異なります。

$ echo $$
12366
$

その後、別の端末で実行します。

$ strace -f -o blah -p 12366

その後、最初の端末に戻ります。

$ ./pg
pid=12676 pgid=12676
pid=12677 pgid=12676
$

次にシステムコールを確認しますcontrol+cstrace

$ egrep 'exec|pgid' blah
12366 setpgid(12676, 12676)             = 0
12676 setpgid(12676, 12676 <unfinished ...>
12676 <... setpgid resumed> )           = 0
12676 execve("./pg", ["./pg"], [/* 23 vars */]) = 0
12676 write(1, "pid=12676 pgid=12676\n", 21 <unfinished ...>
12677 write(1, "pid=12677 pgid=12676\n", 21 <unfinished ...>

bashこのsetpgid呼び出しを使用してプロセスグループを設定することによって、pgプロセスをシェルに依存しないプロセスグループに配置します。 (setsid(2)システムコールを探している場合は、プロセスグループを調整する別の方法になります。)

おすすめ記事