2014-02-19 16 views
0

Я пытаюсь создать 2 дочерних процесса с помощью fork() и синхронизировать их, чтобы они отображали сообщение один за другим пять раз бесконечно.3 Синхронизация процессов с использованием 2-х труб

e.g. Process 1 has process (pid) 
     ... 
     Process 2 has process (pid) 
     ... 
     Process 3 has process (pid) 
     ... 
     Process 1 has process (pid) 
     ... 
     ... 

Я знаю, что это можно было бы сделать проще, используя 3 трубы, но мне было интересно, если это будет возможно сделать это только с 2. По какой-то причине первый процесс никогда не получает возможность работать. Имейте в виду, что я могу использовать трубы только для решения этой проблемы.

#include <sys/types.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 

int main() 
{ 
    pid_t p, p1, mypid; 
    int i; 
    int a = 1; 
    int b = 1; 
    int fd[2];  
    int fd1[2]; 
    pipe(fd); 
    p = fork(); 
    if (p < 0) {perror("Fork"); exit(1); } 
    else if (p == 0) 
    { 
     mypid = getpid();   
     while(1) 
     {   
      close(fd[1]);  
      if (read(fd[0], &a, sizeof(int)) == 0)     
      {   
       for(i = 0; i < 5; i++) {printf("Process 2 has process %d\n", mypid); }  
       close(fd[0]);  
       a = 1;    
       write(fd[1], &a, sizeof(int)); } } 
     } 
    else 
    { 
     p = fork(); 
     if (p < 0) {perror("Fork"); exit(1); } 
     pipe(fd1);   
     if (p > 0) 
     { 
      mypid = getpid();    
      while(1) 
      {    
       close(fd1[1]);   
       if (read(fd1[0], &b, sizeof(int)) == 1) 
       { 
        for(i = 0; i < 5; i++) {printf("Process 1 has process %d\n", mypid); }     
        close(fd[0]); 
        a = 0;     
        write(fd[1], &a, sizeof(int)); }        
       close(fd[1]);    
       if ((read(fd1[0], &b, sizeof(int)) == 0) && (read(fd[0], &a, sizeof(int)) == 1))     
       { 
        close(fd1[0]); 
        b = 0; 
        write(fd1[1], &b, sizeof(int)); } 
      } 
     }   
     else 
     {    
      while(1) 
      {     
       close(fd1[1]); 
       if (read(fd1[0], &b, sizeof(int)) == 0) 
       {    
        mypid = getpid();  
        for(i = 0; i < 5; i++) {printf("Process 3 has process %d\n", mypid); } 
        close(fd1[0]);   
        b = 1;     
        write(fd1[1], &b, sizeof(int)); } 
      }   
     } 
    } 
    return(1); } 

-It проект для моего класса UNIX, так что я был бы очень признателен, если вы только что указали на мои ошибки вместо того, чтобы решить это для меня. -I думаю, я неправильно понял концепцию трубы/прочитал. Пожалуйста, дайте мне знать, если я что-то пропустил и, возможно, свяжусь с источником, чтобы получить более конкретные детали. -Программа может содержать некоторые незначительные ошибки (Missing {} и т. Д.).

ответ

2

С трубой вы получаете два дескриптора файлов, соединенных между собой трубкой. Когда вы создаете дочерний процесс, дескрипторы файла копируются в дочерний процесс. Для целей IPC эти два процесса затем должны согласовать, какой процесс использует тот конец трубы. Неважно, родитель ли получает конец 0, а ребенок получает конец 1 или наоборот. Важно то, что они согласны. Представьте это как физическая труба, соединяющая две комнаты. Если вы находитесь в одной комнате, вы можете поместить вещи в трубу или взять материал, но вы делаете это только на одном конце.

В вашей программе оба родителя и ребенка пытаются закрыть один и тот же конец трубы, а затем попытаться использовать один и тот же противоположный конец трубы. Ваша труба - ведро. :) Чтобы исправить это, у ваших детей, закройте конец канала, который вы читаете/записываете в родительском. В родительском процессе закройте конец канала, который вы читаете/записываете в дочерних элементах. Я подозреваю, что вы добьетесь большего успеха.