gpt4 book ai didi

c - 使用 setpgid() 对子进程进行分组

转载 作者:太空狗 更新时间:2023-10-29 11:09:44 26 4
gpt4 key购买 nike

我就是不明白。

我的进程树:

     0
/ \
1 2
/ \
5 3
/
4

我想创建一个进程组(3、4、5),并向该组发送一个信号,例如 2。

我这样试过:

setpgid(pid3, pid3);
setpgid(pid4, pid3);
setpgid(pid5, pid3);

...

kill(-pid3, SIGUSR1);

我应该把我的 setpgid() block 放在哪里?我尝试将它放在 3、0 和所有其他进程中,但是 setpgid() 返回“没有这样的进程”或“不允许操作”。

pids 存储在文件中,所以我在调用 setpgid()

之前检索它们

最佳答案

一个进程可以设置只有它自己或它的任何子进程的进程组ID。此外,在子进程调用其中一个 exec 函数后,它无法更改其子进程之一的进程组 ID。 --APUE

在我看来,

1.祖 parent 不能对他的孙子使用setgpid(),你可以很容易地检查这一点。也就是说,下面的pid 0中的代码将不起作用:

setpgid(pid3, pid3); 
setpgid(pid4, pid3);
setpgid(pid5, pid3);

2.你只能用setgpid()来改变自己的chill pgid,你不能在pid 3中写setpgid(pid5, pid3),因为pid 3和pid 5不是父子。

所以,你最好自己使用 setgpid(someone's pid, pgid)。

但是一个进程如何知道其他进程的进程号呢?一种方法是共享内存。

这是我刚写的一个粗略但有点复杂的实现,它没有考虑进程同步。它按你的预期工作。

#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

关于c - 使用 setpgid() 对子进程进行分组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16639275/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com