2016-12-07 14 views
1

Я искал и читал руководства, но все еще не могу получить механизм трубы. Я делаю программу, которая должна делать следующее:C - использование различных концов труб в разных проходах

  1. Родительский процесс создает трубу, два дочерних процесса и ждет.

    1. Первый ребенок генерирует пары случайных чисел и передает их промежутком между вторым процессом через трубу. Он продолжается до получает сигнал от родителя.
    2. Второй ребенок перенаправляет его на вход, поэтому он является выходным из первого дочернего элемента и перенаправляет вывод в файл out.txt. Затем он выполняет уже скомпилированную программу, вычисляя GCD чисел из (1);
  2. Родитель закрывает трубку и убивает ребенка.

Так что я получил этот код С (я уменьшил его так, чтобы пост может соответствовать правилам):

const int PIPE_READEND=0; 
const int PIPE_WRITEEND=1; 

     (...) 
if (child1 == 0) { 
     //Child1 code here 
     close(fd[1]); 

     struct sigaction sa; 
     sa.sa_handler = sigHandler; 
     sigemptyset(&sa.sa_mask); 
     sa.sa_flags = 0; 
     if (sigaction(SIGUSR1,&sa,NULL) == -1){ //Handling SIGUSR1 signal 
      perror("Signal handling unexpected error"); 
      exit(errno); 
     } 
     int a,b; 
     srand(time(&t)); 
     if (dup2(fd[PIPE_READEND],1) < 0){ //Redirecting stdout to the pipe fd. 
      perror("In Child1 Redirecting stdout to pipe error"); 
      exit(errno); 
     } 
     close(fd[0]); 
     while(1){ 
      a = rand(); 
      b = rand(); 
      printf("%d %d\n", a, b); 
      sleep(1); 
     } 


     (...) 
if ((child2 = fork()) < 0){ 
     perror("Fork error in Child2 process"); 
     exit(errno); 
    } else if (child2 == 0){ 
     //Child2 code here 
     close(fd[PIPE_READEND]); 
     FILE *outfile = fopen("out.txt","w"); 
     dup2(fd[PIPE_WRITEEND],0); 
     dup2(outfile,1); 
     close(fd[PIPE_WRITEEND]); 
     execl("c1/main","main",(char *)NULL); 

Проблема заключается в том, после его выполнения, out.txt остается пустым. Я разочарован индексами массива труб, который используется для чего.

+0

Как мы не имеем код другой программы. Мы не можем больше вам помочь. У вас много странного кода. Например, вы заменяете 1 по трубе [0]. Это бесполезно, потому что запись на выходе из трубы не работает. Я не понимаю, почему вы хотите использовать сигнал. – Stargateur

+0

Вам нужно прочитать с конца чтения и записать в конец записи. Вы читаете с конца записи и записываете в конец чтения. – alvits

ответ

1

Вы пишете и читаете неправильные индексы трубы. Вам необходимо их изменить:

Это перенаправление stdout на вход трубы.

close(fd[0]); 
    dup2(fd[1], STDOUT_FILENO); 

Это переназначает выход трубы на stdin.

close(fd[1]); 
    dup2(fd[0], STDIN_FILENO); 

dup2 Также принимает целое число, а не указатель, так что вы должны сделать:

f = fopen("out.txt", "w"); 
    dup2(fileno(f), STDOUT_FILENO); 
+0

Это, кажется, работает отлично. Спасибо! –

1
FILE *outfile = fopen("out.txt","w"); 
    dup2(fd[PIPE_WRITEEND],0); 
    dup2(outfile,1); 

Это не имеет никакого смысла. Функция dup2 не принимает параметр FILE *. Использовать open, а не fopen.

+0

@ Начальник Эмм, спасибо, все еще пуст. Однако я заметил что-то. Программа, выполняющая в 'execl()' командные подсказки "DONE" на stdout, когда это делается. Моя программа выводит сообщение «TERMINATED», когда это делается. И «DONE» появляется перед «TERMINATED», поэтому 'execl()' как-то не дожидается основной программы и ее номеров. Однако не могу понять, как это сделать. –

+0

@DavidSchwartz Спасибо за совет. Я немного изменил его, но все равно получаю ту же проблему. int fdOut = open ("out.txt", O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); dup2 (fdOut, 1); // Перенаправление вывода на «out.txt» close (fd [PIPE_WRITEEND]); execl («c1/main», «main», (char *) NULL); Соблюдайте любую идею, где ошибка может быть? –

 Смежные вопросы

  • Нет связанных вопросов^_^