我正在试图让两个进程通过命名管道进行通信。就像这样,首先我的过程" prac"这些孩子通过信号(下面的代码中的scanf)接收到他们不得不接受一个" execl(dadesPrac)"谁只需要通过FIFO写一个字符串给他的父母。问题是,似乎它在FIFO中被卡住了。 我甚至不能通过终端看到消息:
" printf("我终于写了%s \ n",缓冲区);"
写作的过程得到了"名称"通过execl prevoiusly的参数说明的fifo,它是这样的:
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <fcntl.h>
#define MAX_BUF 64
#include <string.h>
#include <errno.h>
#include <signal.h>
int main(int argc, char **argv){
int fd;
char buffer[MAX_BUF] = "";
char aux[MAX_BUF] = "";
int MaxTemp;
printf("%s , %s , %s \n",argv[0],argv[1],argv[2]);
if(argc == 3){
srand(time(NULL));
MaxTemp = (rand() % 50) + 10;
printf("I'M IN EXEC\n");
sprintf(aux,"%i",MaxTemp);
printf(" MAXTEMP %s\n",aux);
strcat(buffer,aux);
strcat(buffer,argv[2]);
printf("what i'm gonna write is %s\n",buffer);
fd = open(argv[1],O_WRONLY);
write(fd, buffer, sizeof(MAX_BUF));
printf("i finally wrote %s\n",buffer);
close(fd);
//unlink(argv[1]);
}else{
perror(" number of parameters incorrect");
}
printf("i'm gonna exit\n");
_exit(0);
}
流程实践的代码如下:
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <fcntl.h>
#define MAX_BUF 64
#include <string.h>
#include <errno.h>
#include <signal.h>
int senyal = 0;
void empezar(int signum){
senyal++;
}
void make_fifo(char * myfifo){
/* crea l'arxiu fifo en cas de que ja no existeixi previament*/
int m;
if ((m = mkfifo(myfifo, 0666)) < 0){
if (errno != EEXIST){
perror ("mkfifo");
}
}
}
int main(int argc,char **argv) {
int m;
int pid11;
int fd, pid1,pid2,pid3,auxint,auxint2,status;
char * npipe1 = "/tmp/npipe1";
char buf[MAX_BUF];
char aux[MAX_BUF];
pid1 = fork();
if(pid1 == 0){
//child1
make_fifo(npipe1);
pid11 = fork();
if(pid11 == 0){
//grandson1
printf("inside grandson \n");
signal(SIGUSR1,empezar);
while(!senyal){
printf("im in the while\n");
sleep(1);
}
printf("i'm out of the while\n");
sprintf(aux,"%i",getpid());
execl("./dadesPrac","dadesPrac",npipe1,aux,NULL);
}
printf("almost waitpid\n");
wait(NULL);
printf("after waitpid\n");
fd = open(npipe1,O_RDONLY);
read(fd, buf, sizeof(MAX_BUF));
close(fd);
printf("%s",buf);
//do sql stuff
}
printf("i'm in dad \n");
scanf("%i",&auxint2);
kill(pid11,SIGUSR1);
wait(NULL);
return 0;
}
我老实地输了,对不起可能的错误感到抱歉,而不是母语人士,所以很难清楚地解释自己。
答案 0 :(得分:1)
我认为问题在于你做叉子和处理信号的方式。
第一次进行prac
分叉时,您已将孩子的pid分配给pid1
。
父(原始prac
)然后调用scanf()并等待。
您的子进程(prac
child)再次调用fork(),并将孙子的pid分配给pid11
(prac
孙子。)
然后,您尝试使用父(原prac
)将信号发送给孙子(pid11
)。但是,父级没有孙子的正确pid,因为孙子是由子代码而不是父代创建的。父进程中的pid11
仍然是其默认值,在代码中未定义。
因此,当您输入一些输入时,父项执行kill()
函数,如果pid11
的默认值为0,则表示将信号发送到具有相同进程组ID的所有进程(参考kill()
)。如果pid11
不为0,则信号将发送到错误的进程。
此外,您只为孙子进程编写安装信号处理程序,因此父进程和子进程都被终止。因此没有人会读取FIFO。