可以参看UNIX环境高级编程的相关章节。
为了搞清楚进程组之间的关系,我们做如下的实验:
编写程序:
/*test.c*/ #include "../include/apue.h" void main() { pid_t pid; char *args[] = {"/bin/echo", "Hello", "World!", NULL }; if((pid = fork()) < 0) err_sys("fail to fork!"); else if(pid == 0) { execve("./test1", args, NULL); } /* if((pid = fork()) < 0) err_sys("fail to fork!"); if(pid == 0) { execve("./test2", NULL, NULL); } */ while(1) { }; } /*test1.c*/ #include <stdio.h> int main(int args, char* argv[]) { char s[5] = "ABCD"; while(1) {} return; } /* in test2.c */ #include <stdio.h> #include <stdlib.h> int main() { pid_t pid; pid = fork(); if (pid <0) { printf("fork err\n"); exit(-1); } else if (pid == 0) { /* in child process */ execve("./test3", NULL, NULL); } while(1) {} } /*test3.c*/ #include <stdio.h> void main() { while(1) { //printf("test3\n\n"); } }
实验一:
编写shell文件,shell文件的作用是同时启动两个进程:
#!/bin/bash
./test | ./test2
$ps -ejH
PID PGID SID TTY TIME CMD
3888 3888 3888 pts/4 00:00:00 bash
4961 4961 3888 pts/4 00:00:00 ps
4394 4394 4394 pts/0 00:00:00 bash
4957 4957 4394 pts/0 00:00:00 test
4959 4957 4394 pts/0 00:00:00 test1
4958 4957 4394 pts/0 00:00:00 test2
4960 4957 4394 pts/0 00:00:00 test3
$pstree -H 4394
|-gnome-terminal
| |-bash结果分析:
PID为4394的进程是我开启的用于运行程序的终端,也就是一个会话(session),其ID为4394。在该session下运行的程序的SID当然都是
4394.我们同时运行了两个进程test和test2,其PID分别为4057和4958,其组ID都是4057。看到,test和test2同属一个进程组,其组ID为该
组创建的第一个进程的ID,即test的ID。由test和test2创建的子进程的组ID同样为4057。
实验二:
$./test & //在后台运行test
$./test2 & //在后台运行test2
PID PGID SID TTY TIME CMD
2697 1501 1501 ? 00:08:20 gnome-terminal
2705 1501 1501 ? 00:00:00 gnome-pty-helpe
3050 3050 3050 pts/1 00:00:00 bash
3888 3888 3888 pts/4 00:00:00 bash
5294 5294 3888 pts/4 00:00:00 ps
4394 4394 4394 pts/0 00:00:00 bash
5288 5288 4394 pts/0 00:00:05 test
5289 5288 4394 pts/0 00:00:04 test1
5290 5290 4394 pts/0 00:00:00 test2
5291 5290 4394 pts/0 00:00:01 test3
$pstree -all
|-gnome-terminal
| |-bash
| | `-pstree -all
| |-bash
| |-bash
| | |-test
| | | `-test1 Hello World!
| | `-test2
| | `-(test3)
| |-gnome-pty-helpe
| `-3*[{gnome-terminal}]
实验结果分析:
我们先后运行了两个进程,可以看到其组ID是不一致的。
实验三:
修改test.c源程序,取消对注释部分的注释,重新编译
$gcc -g -o test test.c
$./test
PID PGID SID TTY TIME CMD
2697 1501 1501 ? 00:08:20 gnome-terminal
2705 1501 1501 ? 00:00:00 gnome-pty-helpe
3050 3050 3050 pts/1 00:00:00 bash
3888 3888 3888 pts/4 00:00:00 bash
5397 5397 3888 pts/4 00:00:00 ps
4394 4394 4394 pts/0 00:00:00 bash
5393 5393 4394 pts/0 00:00:01 test
5394 5393 4394 pts/0 00:00:01 test1
5395 5393 4394 pts/0 00:00:00 test2
5396 5393 4394 pts/0 00:00:01 test3
|-gnome-keyring-d --daemonize --login
| `-4*[{gnome-keyring-}]
|-gnome-screensav --no-daemon
| `-2*[{gnome-screensa}]
|-gnome-terminal
| |-bash
| | `-pstree -all
| |-bash
| |-bash
| | `-test
| | |-test1 Hello World!
| | `-test2 Hello World!
| | `-(test3)
| |-gnome-pty-helpe
| `-3*[{gnome-terminal}]
结果分析:
由进程树可以看到test3是test2的子进程,test2是test的子进程。其组ID都是test的PID。
现在,我们先告一段落,过段时间我们通过杀死进程来进一步分析进程/进程组,线程/线程组之间的关系。