日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【进程】进程组

發布時間:2023/11/30 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【进程】进程组 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、進程組

1. 進程組

(1)進程組,也稱之為作業,BSD與1980年前后向UNIX中增加的一個新特性,代表一個或多個進程的集合。每個進程都屬于一個進程組,在waitpid函數和kill函數的參數中都曾經使用到,操作系統設計的進程組的概念,是為了簡化對多個進程的管理。

當父進程創建子進程的時候,默認子進程與父進程屬于同一個進程組,進程組ID等于進程組第一個進程ID(組長進程)。所以,組長進程標識:其進程組ID等于其進程ID.

組長進程可以創建一個進程組,創建該進程組的進程,然后終止,只要進程組中有一個進程存在,進程組就存在,與組長進程是否終止無關。

(2)kill發送給進程組

使用?kill -n -pgid?可以將信號 n 發送到進程組 pgid 中的所有進程。例如命令?kill -9 -4115?表示殺死進程組 4115 中的所有進程。


2. getpgid、getpgrp函數原型:

pid_t getpgrp(void); pid_t getpgid(pid_t pid);

分析:

  • 函數1:獲取當前進程的進程組ID
  • 函數2:如果pid = 0,那么該函數作用和getpgrp一樣。

?

3. setpgid函數函數原型:改變進程默認所屬的進程組,通常可用來加入一個現有的進程組或新進程組。

int setpgid(pid_t pid, pid_t pgid);

分析:將參數1對應的進程,加入參數2對應的進程組中。

注意:

  • 如改變子進程為新進程組,用fork后,exec前。
  • 權級問題:非root進程只能改變自己創建的子進程,或有權限操作的進程。

4. 測試代碼:

#include <stdio.h> #include <stdlib.h> #include <unistd.h>int main() {pid_t pid;if ((pid = fork()) < 0) {perror("fork");exit(1);}else if (pid == 0) //子進程{printf("child PID = %d\n", getpid());printf("child Group ID = %d\n", getpgid(0)); //返回組idsleep(7);printf("-------Group ID of child id change to %d\n", getpgid(0));exit(0);}else if (pid > 0) //父進程{sleep(1);setpgid(pid, pid); //讓子進程自立門戶,成為進程組組長,以它的pid為進程組 id sleep(13);printf("\n");printf("parent PID = %d\n", getpid());printf("parent's parent PID = %d\n", getppid());printf(" parent Group ID = %d\n", getpgid(0));sleep(5);setpgid(getpid(), getppid()); //改變父進程組id為父進程的父進程printf("\n-------Group ID of parent is change to %d\n", getpgid(0));while (1);}return 0; }

輸出結果:

?

二、進程組的應用

1. 實驗一:

題目:利用進程扇完成一個小實驗。該進程扇有 1 個父進程和 3 個子進程,我們希望達到圖 1 中的效果,即將進程 0 (父進程)和進程 1 設置成一組,假設為組 1,將進程 2 和 進程 3 設置成另一個組,假設為組 2. 另外,我們希望進程 0 和進程 2 分別是這兩個組的組長。? ?
?

1. 測試代碼:

#include <unistd.h> #include <string.h> #include <stdio.h> #include <stdlib.h> #include <errno.h>int main() {int pid, i;int group1, group2;// 設置父進程(進程 0)為組長 setpgid(getpid(), getpid());group1 = getpgid(getpid());for (i = 1; i <= 3; ++i) {pid = fork();if (pid == 0) child{if (i == 1) {// 如果 group1 根本不存在,就會出問題。// 比如進程 0 已經運行結束。setpgid(getpid(), group1);}else if (i == 2) {setpgid(getpid(), getpid());group2 = getpgid(getpid());}else if (i == 3) {// 試想如果進程 2 還沒運行,進程 3 先運行了,// 這時候 group2 還未進行設置,這里就會有問題。// 或者進程 2 已經結束,那進程 3 的設置也會失敗setpgid(getpid(), group2);}break;}else if (pid < 0) {perror("fork");return -1;}}printf("進程 %d, pid: %d -> ppid: %d, pgid: [%d], (%s)\n", i % 4, getpid(), getppid(), getpgid(getpid()), strerror(errno));while (1) sleep(1);return 0; }

輸出結果:?

測試代碼:

#include <unistd.h> #include <stdlib.h> #include <stdio.h> #include <sys/wait.h>int main(void) {setpgid(getpid(), getpid());pid_t group1 = getpgid(getpid());pid_t group2;int i = 0;for(; i < 3; ++i){pid_t pid = fork();if(pid < 0){perror("fork error");exit(1);}else if(pid > 0){// parent processif(i == 0)setpgid(pid, group1);if(i == 1){setpgid(pid, pid);group2 = getpgid(pid);}if(i == 2)setpgid(pid, group2);}else{// child processif(i == 0)setpgid(getpid(), group1);if(i == 1){setpgid(getpid(), getpid());group2 = getpgid(getpid());}if(i == 2)setpgid(getpid(), group2);break;}}printf("pid:%d, ppid:%d, pgid:%d\n", getpid(), getppid(), getpgid(getpid()));for(int i = 0; i < 3; ++i)wait(0);return 0; }

輸出結果:

2. 實驗二:

題目:利用進程扇完成一個小實驗。該進程扇有 1 個父進程和 3 個子進程,我們希望達到圖 1 中的效果,即將進程 0 (父進程)和進程 1 設置成一組,假設為組 1,將進程 2 和 進程 3 設置成另一個組,假設為組 2. 另外,我們希望進程 0 和進程 2 分別是這兩個組的組長。

測試代碼:

#include <unistd.h> #include <string.h> #include <stdio.h> #include <stdlib.h> #include <errno.h>int main() {int pid, i;int group1, group2;setpgid(getpid(), getpid());group1 = getpgid(getpid());for (i = 0; i < 3; ++i) {pid = fork();if (pid > 0) //父進程{if (i == 0) {setpgid(pid, pid);group2 = getpgid(pid);} else if (i == 1) {setpgid(pid, group1);} else if (i == 2){setpgid(pid, group2);} break;} else if (pid == 0) //子進程{if (i == 0) {setpgid(getpid(), getpid());group2 = getpgid(getpid());} else if (i == 1) {setpgid(getpid(), group1);} else if (i == 2) {setpgid(getpid(), group2);} } else if (pid < 0) {perror("fork");return -1; } }printf("進程 %d, pid: %d -> ppid: %d, pgid: [%d]\n", i, getpid(), getppid(), getpgid(getpid()));while(1) sleep(1);return 0; }

?

總結

以上是生活随笔為你收集整理的【进程】进程组的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。