我的代码分叉n个进程。当到达最后一个进程时,它通过FIFO向顶级进程发送消息以终止所有进程。我的代码工作得很好,除了最后一个进程永远不会达到我的信号并且永远不会被顶级进程杀死。
代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/shm.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <sys/signal.h>
#include <unistd.h>
#include <errno.h>
#include <stdbool.h>
#define MAX_BUF 1024
int *ptr;
int numprocs;
void signal_handler(int sig){
int currpid = getpid();
int lev;
int i;
for(i = 1; i < numprocs; i++){
if(ptr[i] == currpid){
lev = numprocs - i;
break;
}
}
fprintf(stdout,"EXITING: Level %d process with pid=%d, child of ppid=%d.\n", lev, ptr[i], ptr[i-1]);
exit(0);
}
int main(int argc, char **argv){
numprocs = atoi(argv[1]);
int lev = numprocs;
bool x = true;
//create shared memory
const int SIZE = numprocs * sizeof(int);
const char *name = "dleggio1OS";
int shm_fd;
shm_fd = shm_open(name, O_CREAT | O_RDWR, 0666);
ftruncate(shm_fd, SIZE);
ptr = mmap(0, SIZE, PROT_WRITE, MAP_SHARED, shm_fd, 0);
*ptr = getpid();
//create unnamed pipe
int pfds[2];
char buf[30];
if(pipe(pfds) == -1){
perror("pipe");
exit(1);
}
//create fifo
int fd;
char *myfifo = "/tmp/dleggio1fifo";
mkfifo(myfifo, 0666);
pid_t pid = fork();
if(pid == 0){ //first child ..... keep forking
//read unnamed pipe
close(pfds[1]);
if(read(pfds[0], buf, 3) <= 0){
perror("child");
exit(1);
}
int check = atoi(buf);
fprintf(stdout,"ALIVE: Level %d process with pid=%d, child of ppid=%d.\n", check, getpid(), getppid());
//write to shared memory
ptr[numprocs - check] = getpid();
signal(SIGUSR1,signal_handler);
int i;
lev--;
for(i = 2; i < numprocs; i++){
//create named pipe
int pfds[2];
char buf[30];
if(pipe(pfds) == -1){
perror("pipe");
exit(1);
}
lev--;
pid_t pid;
if((pid = fork()) < 0){
perror("fork");
exit(1);
}
else if(pid == 0){
//update shared memory
ptr[i] = getpid();
//read from named pipe
close(pfds[1]);
if(read(pfds[0], buf, 3) <= 0){
perror("child");
exit(1);
}
int check = atoi(buf);
fprintf(stdout,"ALIVE: Level %d process with pid=%d, child of ppid=%d.\n", check, getpid(), getppid());
if(check == 1){
//write to fifo
fd = open(myfifo, O_WRONLY);
write(fd,"leaf",sizeof("leaf"));
close(fd);
unlink(myfifo);
signal(SIGUSR1,signal_handler);
}
signal(SIGUSR1,signal_handler);
}
else{
//write to named pipe
close(pfds[0]);
char hold[3];
sprintf(hold,"%d",lev);
if(write(pfds[1], hold, 3) <= 0){
perror("parent");
exit(1);
}
wait(NULL);
}
}
}
else{ //top level
fprintf(stdout,"ALIVE: Level %d process with pid=%d, child of ppid=%d.\n", lev, getpid(), getppid());
//write to unnamed pipe
lev--;
close(pfds[0]);
char hold[3];
sprintf(hold,"%d",lev);
if(write(pfds[1], hold, 3) <= 0){
perror("parent");
exit(1);
}
//read from fifo
char buff[MAX_BUF];
fd = open(myfifo,O_RDONLY);
read(fd,buff,MAX_BUF);
close(fd);
unlink(myfifo);
char *comp = "leaf";
if(strcmp(buff,comp) == 0){
int j;
for(j = 0; j < numprocs; j++) printf("%d\n",ptr[j]);
for(j = 1; j < numprocs; j++) kill(ptr[j],SIGUSR1);
shm_unlink(name);
fprintf(stdout,"EXITING: Level %d process with pid=%d, child of ppid=%d.\n", numprocs, getpid(), getppid());
exit(0);
}
}
}
输出:
./prog1 4
ALIVE: Level 4 process with pid=5129, child of ppid=4692.
ALIVE: Level 3 process with pid=5130, child of ppid=5129.
ALIVE: Level 2 process with pid=5131, child of ppid=5130.
ALIVE: Level 1 process with pid=5132, child of ppid=5131.
5129
5130
5131
5132
EXITING: Level 4 process with pid=5129, child of ppid=4692.
EXITING: Level 3 process with pid=5130, child of ppid=5129.
EXITING: Level 2 process with pid=5131, child of ppid=5130.