我只是没有得到所有的东西。
我的进程树:
0 / \ 1 2 / \ 5 3 / 4
我想创build一个进程组(3,4,5),并从这个组发送信号,比如2。
我这样试了:
setpgid(pid3, pid3); setpgid(pid4, pid3); setpgid(pid5, pid3); ... kill(-pid3, SIGUSR1);
我应该在哪里放置我的setpgid()
块? 我试着把它放在setpgid()
和其他所有进程中,但是setpgid()
返回“没有这样的进程”或“不允许的操作”。
pids存储在文件中,所以我只是在调用setpgid()
之前检索它们。
一个进程可以设置只有自己或其任何子进程组ID。 而且,在子进程调用其中一个exec函数之后,它不能更改其子进程的组进程ID。 –APUE
我的想法是,
1.祖父母不能使用setgpid()和它的成绩,你可以很容易的检查这个。也就是说,下面的pid 0中的代码将不起作用:
setpgid(pid3, pid3); setpgid(pid4, pid3); setpgid(pid5, pid3);
2.你只能使用setgpid()来改变自己和chilledd的pgid,你不能在pid3中写下setpgid(pid5,pid3),因为pid3和pid5不是父和子。
所以,你最好使用setgpid(某人的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