如何在Linux上的c中的父进程和子进程之间进行乒乓球
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在Linux上的c中的父进程和子进程之间进行乒乓球相关的知识,希望对你有一定的参考价值。
[我希望我的主进程创建一个管道和一个子进程,然后子进程向管道发送一个数字(以0开头)并向父级发送信号,父级从管道中读取,如果该数量小于5,则打印它,增加将其乘以1,然后通过管道将其传递回并向孩子发出信号。
我的问题是,我没有设法将它们作为“乒乓”进行同步。
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/types.h>
#include <unistd.h>
void parentSignal(int signum);
void childSignal(int signum);
int pfd[2];
int fid, cid;
int val = 0;
void parentSignal(int signum){
sleep(0);
read(pfd[0], &val, sizeof(val));
printf("my pid is: %d, X = %d
",fid, val); val++;
if (val==6) {
puts("Parent is going to be terminated");
kill(cid, SIGTERM);
kill(fid, SIGTERM);
}
}
void childSignal(int signum){
sleep(0);
read(pfd[0], &val, sizeof(val));
printf("my pid is: %d, Y = %d
",cid, val); val++;
if (val==6) {
puts("Childd is going to be terminated");
kill(cid, SIGTERM);
kill(fid, SIGTERM);
}
}
int main(){
if (pipe(pfd) < 0){ printf("Pipe Failed"); }
pid_t pid = fork();
if (pid == 0) {// We are in child
fid=getppid();
signal(SIGUSR1, parentSignal);
write(pfd[1], &val, sizeof(val));
kill(fid, SIGUSR1);
while (1){
sleep(0);
write(pfd[1], &val, sizeof(val));
kill (fid, SIGUSR1);
}
}
else if (pid > 0) {// We are in parent
cid = pid;
signal(SIGUSR1, childSignal);
while (1){
sleep(0);
write(pfd[1], &val, sizeof(val));
kill (cid, SIGUSR1);
}
}
else { puts("Fork Failed !!"); }
close(pfd[0]);
close(pfd[1]);
return 0;
}
有人可以帮助我修复代码,以使输出结果是:
- 0
- 1
- 2
- 3
- 4
- 5
- 孩子将要被处决
- 父母将会是已终止
答案
示例源中存在一些计时问题。
一旦任何一个进程写入管道,就无法保证另一个进程将在编写者的while()循环的下一次迭代之前运行并从管道中读取。 kill()请求将向目标进程发送信号并返回;调用过程中的执行继续进行,并且可能再次将相同的数据写入()管道。系统何时调度和运行任何进程[线程]取决于系统调度程序。
BTW:请注意,sleep(0)应该立即返回。
通常,需要在过程之间进行同步以可靠地产生所描述的乒乓序列的形式。示例:进程向管道写入数据后,可以调用sigsuspend()之类的东西;其他调用read()后跟带有不同信号的kill()来解锁第一个进程;也许是SIGUSR2,请检查目标系统上的特定信号语义。
或者,您可以使用2个线程运行1个进程并共享一个同步对象;一种想法可能使用pthread_cond_wait()和pthread_cond_signal()。
以上是关于如何在Linux上的c中的父进程和子进程之间进行乒乓球的主要内容,如果未能解决你的问题,请参考以下文章