【问题标题】:How to ping-pong between parent and child processes in c on linux如何在linux上的c中的父进程和子进程之间进行ping-pong
【发布时间】:2020-09-12 05:04:22
【问题描述】:

我希望我的主进程创建一个管道和一个子进程,而不是子进程向管道发送一个数字(以 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\n",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\n",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
  • 孩子将被终止
  • 父母将是 终止

【问题讨论】:

  • 您不应该使用两个管道吗?一个用于父写/子读,另一个用于通信?只是问,没有测试任何一种方式......
  • 我不认为这是我的问题..
  • 我终于试过了...不需要 2 个管道 :) 见 pastebin.com/QLQEgECk
  • 真是个好人。但我需要通过“SIGUSR1”做“乒乓球”。

标签: c linux process signals ipc


【解决方案1】:

示例源中存在一些时间问题。

一旦任一进程写入管道,就无法保证另一个进程将在编写器的 while() 循环的下一次迭代之前运行并从管道读取。一个 kill() 请求将向目标进程发送一个信号并返回;调用进程中的执行继续,并且可以再次将相同的数据写入()到管道中。任何进程 [线程] 何时被调度和运行取决于系统调度程序。

顺便说一句:注意 sleep(0) 应该立即返回。

通常需要进程之间的同步形式来可靠地产生所描述的乒乓序列。示例:在进程写入管道后,它可以调用类似 sigsuspend();其他调用 read() 后跟一个带有不同信号的 kill() 来解除对第一个进程的阻塞;也许是 SIGUSR2,检查目标系统上的特定信号语义。

或者,您可以使用 2 个线程运行 1 个进程并共享一个同步对象;一种想法可能是使用 pthread_cond_wait() 和 pthread_cond_signal()。

【讨论】:

  • 我会尝试这些建议。如果你想实现我没有拒绝:)
猜你喜欢
  • 1970-01-01
  • 2020-07-12
  • 1970-01-01
  • 2019-06-17
  • 1970-01-01
  • 1970-01-01
  • 2014-03-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多