c - Grouping child processes with setgpid() -
i don't whole thing.
my process tree:
0 / \ 1 2 / \ 5 3 / 4
i want make process group (3, 4, 5), , send group signal from, say, 2.
i tried way:
setpgid(pid3, pid3); setpgid(pid4, pid3); setpgid(pid5, pid3); ... kill(-pid3, sigusr1);
where should place setpgid()
block? tried placing in 3, 0 , every other process, setpgid()
s return either "no such process" or "operation not permitted".
pids stored in files, retrieve them before calling setpgid()
a process can set process group id of only or of children. furthermore, can't change process group id of 1 of children after child has called 1 of exec functions. --apue
in opinion,
1.a grandparent can't use setgpid() gradechild, can check easily.that's say, code in pid 0 below won't work:
setpgid(pid3, pid3); setpgid(pid4, pid3); setpgid(pid5, pid3);
2.you can use setgpid() change one's , itselves chilld pgid,you can't write down setpgid(pid5, pid3) in pid 3, because pid 3 , pid 5 aren't parent , child.
so, you'd better use setgpid(someone's pid, pgid) in itself.
but how can 1 process know other processes' pid? method shared memory.
here 1 rough litte complex implement wrote, don't consider process synchronization.it works expected.
#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 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 %d\n\n",getpid()); exit(0); } void sig_usr4(int signo) { if(signo == sigusr1) printf("recieved sigal in process 4\npid %d\n\n",getpid()); exit(0); } void sig_usr5(int signo) { if(signo == sigusr1) printf("recieved sigal in process 5\npid %d\n\n",getpid()); exit(0); }
output:
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 31364 recieved sigal in process 5 pid 31365 recieved sigal in process 4 pid 31366
Comments
Post a Comment