プロセスグループ


Rev.1を表示中。最新版はこちら

複数のプロセスをまとめてプロセスグループというものが作られます。プロセスグループを作ると親となるプロセスグループにシグナルを送ると、そのグループのプロセスへもシグナルが送られます。httpdはpreforkで前もって複数のプロセス(スレッド)が立ち上がります。親のhttpdを削除すると、すべてのhttpdが削除されます。これは、これらのhttpdがプロセスグループを形成しているからです。
[root@localhost ~]# ps -fje | more
UID        PID  PPID  PGID   SID  C STIME TTY          TIME CMD
root         1     0     1     1  0 19:29 ?        00:00:04 init [3]
root        72     7     1     1  0 19:29 ?        00:00:00 [kseriod]
root       129     7     1     1  0 19:29 ?        00:00:00 [pdflush]
root       130     7     1     1  0 19:29 ?        00:00:01 [pdflush]
root       131     7     1     1  0 19:29 ?        00:00:00 [kswapd0]
root       132     7     1     1  0 19:29 ?        00:00:00 [aio/0]
root       290     7     1     1  0 19:29 ?        00:00:00 [kpsmoused]
root      1511     1  1511  1511  0 19:31 ?        00:00:00 /usr/sbin/sshd
root      1520     1  1520  1520  0 19:31 ?        00:00:00 /usr/sbin/httpd
apache    1557  1520  1520  1520  0 19:31 ?        00:00:00 /usr/sbin/httpd
apache    1558  1520  1520  1520  0 19:31 ?        00:00:00 /usr/sbin/httpd
apache    1559  1520  1520  1520  0 19:31 ?        00:00:00 /usr/sbin/httpd
apache    1560  1520  1520  1520  0 19:31 ?        00:00:00 /usr/sbin/httpd
PPIDは親のプロセスIDをPGIDはプロセスグループ番号です。プロセスグループ番号は親プロセスのIDとなります。下から5つ目のhttpdのPID=1529,PGID=1529で、これがプロセスリーダだと分かります。下の4つのPGIDは1520,また親プロセスも1520ですから、プロセスグループを形成していて、しかもスレッドとして起動されたな。というのが分かります。

プロセスグループのカーネル実装は、do_forkからよばれるcopy_processでtask_struct構造体のpid_t tgidメンバーに設定し、struct list_head thread_groupでリスト化することで実現しています。なお、スレッドでない場合自プロセスIDを設定します。自分が親でグループなし。という感じです。
static struct task_struct *copy_process(unsigned long clone_flags,
・・・・・
     p->pid = pid_nr(pid);
       p->tgid = p->pid;
       if (clone_flags & CLONE_THREAD)
               p->tgid = current->tgid;
・・・・・
      if (clone_flags & CLONE_THREAD) {
               atomic_inc(&current->signal->count);
               atomic_inc(&current->signal->live);
               p->group_leader = current->group_leader;
               list_add_tail_rcu(&p->thread_group, &p->group_leader->thread_group);
・・・・・
シグナル発生時、send_signal経由してよばれるcomplete_signal関数内で、スレッドグループに発生した致命的な(マスクできないってこと?)シグナルを、struct list_head thread_groupをたどることにより、全プロセス(スレッド)に配送しています。
static void complete_signal(int sig, struct task_struct *p, int group)
{
・・・・・
    if (!sig_kernel_coredump(sig)) {
             signal->flags = SIGNAL_GROUP_EXIT;
             signal->group_exit_code = sig;
             signal->group_stop_count = 0;
             t = p;
             do {
                     sigaddset(&t->pending.signal, SIGKILL);
                     signal_wake_up(t, 1);
              } while_each_thread(p, t);
              return;
・・・・・
      }

最終更新 2010/01/21 14:45:06 - north
(2010/01/21 14:45:06 作成)


検索

アクセス数
3584329
最近のコメント
コアダンプファイル - sakaia
list_head構造体 - yocto_no_yomikata
勧告ロックと強制ロック - wataash
LKMからのファイル出力 - 重松 宏昌
kprobe - ななし
ksetの実装 - スーパーコピー
カーネルスレッドとは - ノース
カーネルスレッドとは - nbyst
asmlinkageってなに? - ノース
asmlinkageってなに? - よろしく
Adsense
広告情報が設定されていません。