Как установить ping-pong между родительскими и дочерними процессами в c на linux - PullRequest
0 голосов
/ 25 мая 2020

Я хочу, чтобы мой основной процесс создавал канал и дочерний процесс, а затем дочерний процесс отправлял в канал номер (начинается с 0) и сигналы родительскому, родительский считывает из канала, и если число меньше 5, распечатайте его, увеличивает его на 1 и передает обратно по конвейеру и сигналам дочернему элементу.

моя проблема в том, что мне не удалось синхронизировать c их как «пинг-понг».

#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
  • Дочерний объект будет удален
  • Родительский объект будет удален

1 Ответ

0 голосов
/ 25 мая 2020

В исходном примере есть некоторые проблемы с синхронизацией.

После того, как один из процессов выполнит запись в канал, нет гарантии, что другой процесс будет запущен и прочитан из канала до следующей итерации оператора записи while () л oop. Запрос kill () отправит сигнал целевому процессу и вернется; выполнение в вызывающем процессе продолжается и может снова записать () те же данные в конвейер. Это зависит от системного планировщика, когда какой-либо процесс [поток] будет отправлен и запущен.

Кстати: обратите внимание, что sleep (0) должен возвращаться немедленно.

Обычно это форма синхронизации между процессами необходим для надежного получения описанной последовательности пинг-понга. Пример: после того, как процесс записывает в канал, он может вызвать что-то вроде sigsuspend (); другие вызовы read (), за которыми следует kill () с другим сигналом для разблокировки первого процесса; возможно, SIGUSR2, проверьте семантику c сигналов в вашей целевой системе.

В качестве альтернативы вы можете запустить 1 процесс с 2 потоками и совместно использовать объект синхронизации; одна идея может использовать pthread_cond_wait () и pthread_cond_signal ().

...