我使用两个管道在父进程和子进程之间创建了双向通信。父母和孩子写数据,我能够让他们互相读取数据。父写入数字1到5,并且子写入数字从6到10.但是我希望父项首先开始读取数据,然后按此顺序继续读取从父项切换到子项,直到读取所有数据:6,1, 7,2,8,3,9,4,10,5。我试图将读数与SIGUSR1同步,但是当父母第二次读取时程序停止。我已经搜索了很多,以找到问题所在,并尝试了一些技巧和类似的工作示例,但似乎没有任何帮助。这是我的代码:
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
void paction(int dummy)
{
printf("P*************************************************\n");
}
void caction(int dummy)
{
printf("C*************************************************\n");
}
int main()
{
int pfd[2];
int pfd2[2];
pid_t cfork, pfork;
if (pipe(pfd) == -1 || pipe(pfd2) == -1) {
fprintf(stderr,"Pipe failed");
exit(1);
}
cfork = fork();
signal(SIGUSR1, paction);
if (cfork == -1) {
printf("Fork Failed\n");
exit(1);
}
else if (cfork > 0) { /*parent process*/
int numbers[] = {1, 2,3, 4, 5};
int numbers2[] = { 6, 7,8, 9, 10 };
close(pfd[0]); /*close read end, write and then close write end*/
/*write part*/
int limit = 5;
int i;
for (i = 0; i < limit; i++) {
printf("Parent sends: %d\n", numbers[i]);
write(pfd[1], &numbers[i], sizeof(numbers[i]));
printf("Child sends: %d\n", numbers2[i]);
write(pfd2[1], &numbers2[i], sizeof(numbers2[i]));
}
printf("***************************************************\n");
close(pfd[1]);
close(pfd2[1]);
/*read part/////////////////////////////////////////*/
int temp;
int reads = 5;
int j;
for (j = 0; j < reads; j++) {
sleep(1);
read(pfd2[0], &temp, sizeof(temp));
printf("Parent gets: %d\n", temp);
kill(cfork, SIGUSR1);
pause();
}
/*printf("***************************************************\n");*/
kill( cfork, SIGUSR1 );
close(pfd2[0]);
}
else { /*child process*/
signal(SIGUSR1, caction);
close(pfd[1]);
int temp;
int reads = 5;
int j;
pfork = getppid();
for (j = 0; j < reads; j++) {
sleep(1);
read(pfd[0], &temp, sizeof(temp));
printf("Child gets: %d\n", temp);
kill(getppid(), SIGUSR1);
pause();
}
/*printf("***************************************************\n");*/
close(pfd[0]);
close(pfd2[0]);
}
return 0;
}
我的输出如下:
> Parent sends:1
> Child sends:6
> Parent sends:2
> Child sends:7
> Parent sends:3
> Child sends:8
> Parent sends:4
> Child sends:9
> Parent sends:5
> Child sends:10
> **************************************************************
Parent gets:6
> C************************************************************
> Child gets:1
> P*************************************************************
> Parent gets:7
这就是它停止的时候。 如果有人可以帮助我,我会非常感激,因为我真的想知道问题出在哪里,因为我是C编程和流程的初学者! 提前谢谢
答案 0 :(得分:0)
printf()
不是异步安全函数。在普通代码和信号处理程序中调用printf()
将导致未定义的行为。特别是,printf()
可能需要对输出流进行锁定,而在信号处理程序中获取锁定非常是不可取的(自我死锁的风险)。
答案 1 :(得分:0)
使用信号也许是一个坏主意,但我有一个任务,分配它来使用SIGUSR1。我通过添加:
解决了这个问题static struct sigaction pact, cact;
/* set SIGUSR1 action for parent */;
pact.sa_handler = p_action;
sigaction(SIGUSR1, &pact, NULL);
在为父母分配了第一个动作之后,它运行良好。
谢谢:)