如何在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中的父进程和子进程之间进行乒乓球的主要内容,如果未能解决你的问题,请参考以下文章

C linux中子进程与父进程之间的通信:父进程不阻塞

什么是子进程和父进程

父进程和子进程关系

C - 同时从两个管道(来自两个子进程的父进程)读取?

如何使用 fork() 将数字与父进程和子进程相加 [重复]

如何在父进程和子进程之间发送带有 pipe() 的矩阵?