(1)概念和特性
進程組,也稱之為作業。BSD于1980年前后向Unix中增加的一個新特性。代表一個或多個進程的集合。每個進程都屬于一個進程組。在waitpid函數和kill函數的參數中都曾使用到。操作系統設計的進程組的概念,是為了簡化對多個進程的管理。
當父進程,創建子進程的時候,默認子進程與父進程屬于同一進程組。進程組的ID就是該進程組組長的ID,也就是父進程的ID。一個進程只有一個進程組ID,因此一個進程只能有一個進程組。PPID PID PGID 都大于0 。
可以使用kill -SIGKILL -進程組ID來將整個進程組內的進程全部殺死。(注意權限)
只要進程組中有一個進程存在,進程組就存在,與組長進程是否終止無關。
進程組生存期:進程組創建到最后一個進程離開(終止或轉移到另一個進程組)。一個進程可以為自己或其它進程設置進程組ID,只要權限夠,即root用戶的進程可以設置所有進程的進程組ID。
(2)進程組操作函數
getpgrp函數:獲取當前進程的進程組ID
pid_t getpgrp(void); ??成功:返回調用者的進程組ID;失敗:-1,設置errno
?
getpgid函數:獲取指定進程的進程組ID(注意權限)
pid_t getpgid(pid_t pid);???????? 成功:返回進程組ID;失敗:-1,設置errno
如果pid = 0,那么該函數作用和getpgrp一樣,獲取當前進程的進程組ID。
?
setpgid函數
改變進程默認所屬的進程組。通常可用來加入一個現有的進程組或創建一個新進程組。
int setpgid(pid_t pid, pid_t pgid); ????? 成功:0;失敗:-1,設置errno
將參1對應的進程,加入參2對應的進程組中(可以不存在)。
注意:如改變子進程為新的組,應fork后,exec前;權限問題,非root進程只能改變自己創建的子進程,或有權限操作的進程。
//修改子進程的進程組ID???
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>int main(void)
{pid_t pid;if ((pid = fork()) < 0) {perror("fork");exit(1);} else if (pid == 0) {printf("child PID == %d\n",getpid()); //子進程IDprintf("child Group ID == %d\n",getpgid(0)); // 返回組id//printf("child Group ID == %d\n",getpgrp()); // 返回組idsleep(7);printf("----Group ID of child is changed to %d\n",getpgid(0)); exit(0);} else if (pid > 0) {sleep(1);setpgid(pid,pid); //讓子進程自立門戶,成為進程組組長,以它的pid為進程組idsleep(13);printf("\n");printf("parent PID == %d\n", getpid()); //父進程IDprintf("parent's parent process PID == %d\n", getppid()); //shell進程IDprintf("parent Group ID == %d\n", getpgid(0)); //父進程組IDsleep(5);setpgid(getpid(),getppid()); //改變父進程的組id為shell進程IDprintf("\n----Group ID of parent is changed to %d\n",getpgid(0));while(1);}return 0;
}
[root@localhost 01_session_daemon_test]# ./setpgid
child PID == 19987
child Group ID == 19986
----Group ID of child is changed to 19987
?
parent PID == 19986
parent's parent process PID == 12137
parent Group ID == 19986
?
----Group ID of parent is changed to 12137