進程可以設置進程組ID之前只有本身或任何其子的。此外,在子進程調用其中一個exec函數後,它不能更改其子進程的組進程ID。 --APUE
在我看來,
1.A祖父母不能使用其gradechild setgpid(),您可以檢查此easily.That的說,在PID 0下面的代碼將無法正常工作:
setpgid(pid3, pid3);
setpgid(pid4, pid3);
setpgid(pid5, pid3);
2.you只能使用setgpid()來改變一個人的和itselves chilld PGID,你不能寫在PID 3 setpgid(PID5,PID3),因爲PID 3和pid 5不是父母和孩子。
所以,你最好使用setgpid(someone's pid,pgid)本身。
但是,一個進程如何知道其他進程的PID?一種方法是共享內存。
這裏是一個粗糙而複雜的實現,我剛纔寫道,它不考慮進程同步。它按預期工作。
#include "stdlib.h"
#include "stdio.h"
#include "errno.h"
#include "unistd.h"
#include "string.h"
#include "sys/stat.h"
#include "sys/types.h"
#include "sys/ipc.h"
#include "sys/shm.h"
#include "signal.h"
#define PERM S_IRUSR|S_IWUSR
void sig_usr3(int);
void sig_usr4(int);
void sig_usr5(int);
int main() {
size_t msize;
key_t shmid;
pid_t *pid;
msize = 6 * sizeof(pid_t);
if((shmid = shmget(IPC_PRIVATE, msize , PERM)) == -1) {
fprintf(stderr, "Share Memory Error:%s\n\a", strerror(errno));
exit(1);
}
pid = shmat(shmid, 0, 0);
memset(pid,0,msize);
pid[0] = getpid();
//process 0
if(fork() == 0) {
//process 1
pid = shmat(shmid, 0, 0);
pid[1] = getpid();
if(fork() == 0) {
//process 5
pid = shmat(shmid, 0, 0);
pid[5] = getpid();
while(pid[3]==0)
sleep(1);
if((setpgid(pid[5],pid[3]))==-1)
printf("pid5 setpgid error.\n");
signal(SIGUSR1,sig_usr5);
for(;;)
pause();
}
for(;;)
pause();
exit(0);
}
if(fork() == 0) {
//process 2
pid = shmat(shmid, 0, 0);
pid[2] = getpid();
if(fork() == 0) {
//process 3
pid = shmat(shmid, 0, 0);
pid[3] = getpid();
if((setpgid(pid[3],pid[3]))==-1)
printf("pid3 setpgid error.\n");
if(fork() == 0) {
//process 4
pid = shmat(shmid, 0, 0);
pid[4] = getpid();
if((setpgid(pid[4],pid[3]))==-1)
printf("pid4 setpgid error.\n");
signal(SIGUSR1,sig_usr4);
for(;;)
pause();
}
else {
signal(SIGUSR1,sig_usr3);
for(;;)
pause();
}
for(;;)
sleep(100);
}
if(getpid()==pid[0]) {
int i,flag;
while(!(pid[0]&&pid[1]&&pid[2]&&pid[3]&&pid[4]&&pid[5]))
//wait for all process folking.
sleep(1);
for(i=0;i<6;i++)
printf("process %d,pid:%d\n",i,pid[i]);
kill(-pid[3],SIGUSR1);
}
}
void sig_usr3(int signo) {
if(signo == SIGUSR1)
printf("recieved sigal in process 3\npid is %d\n\n",getpid());
exit(0);
}
void sig_usr4(int signo) {
if(signo == SIGUSR1)
printf("recieved sigal in process 4\npid is %d\n\n",getpid());
exit(0);
}
void sig_usr5(int signo) {
if(signo == SIGUSR1)
printf("recieved sigal in process 5\npid is %d\n\n",getpid());
exit(0);
}
輸出:
process 0,pid:31361
process 1,pid:31362
process 2,pid:31363
process 3,pid:31364
process 4,pid:31366
process 5,pid:31365
recieved sigal in process 3
pid is 31364
recieved sigal in process 5
pid is 31365
recieved sigal in process 4
pid is 31366
謝謝你的很好的例子。當我意識到我不需要任何進程同步,也不需要共享內存技巧時,事情變得更加容易。我在3和4中用'setpgid(getpid(),getpgid(getppid()))'創建了一個組(2,3,4)。這正是我所需要的。顯然,對於更復雜的任務,我會考慮你的解決方案。 –