2016-12-08 3 views
0

Так что я пытаюсь создать программу, которая принимает вход пользователя (цена, например, 50), а затем первый ребенок передает ее второй, второй добавляет 10 (цена сейчас 60), третья затем 50 (сейчас цена 110), а 4 - только печать/возврат окончательной цены. У меня есть fork в цикле, и я создаю каналы, но цена всегда одна и та же, только 10 добавляется в каждом дочернем элементе. Что не так или как исправить, чтобы он работал, как я хочу.C неназванные трубы и вилка для расчета

Мой код:

int main(int argc,char *argv[]) 
{ 
int anon_pipe[2]; 
int n,N=4; 
char value_price[100]; 

if(argc>1) 
{ 
    int price=atoi(argv[1]); 
    printf("%d\n",price); 
    if(pipe(anon_pipe)==-1){ 
     perror("Error opening pipe"); 
     return -1; 
    } 
    for(n = 0; n < N; n++){ 
     switch(fork()){ 
      case -1: 
       perror("Problem calling fork"); 
       return -1; 
      case 0: 
       close(anon_pipe[1]); 

       read(anon_pipe[0],value_price,100); 

       price+=10; 

       sprintf(value_price,"%d \n",price); 
       printf("Price: %d\n",atoi(value_price)); 

       write(anon_pipe[1],value_price,sizeof(value_price)); 

       _exit(0); 
     } 
    } 
    close(anon_pipe[0]); 
    sleep(1); 
    close(anon_pipe[1]); 
} 

return 0; 
} 
+0

Обратите внимание, что у нас есть [документация] (http: // stackoverflow.com/documentation/posix/8082/pipe/26063/connect-two-child-процессы-через-канал # t = 201612081850028838105) для настройки передачи данных от ребенка к ребенку по трубе. –

ответ

1

Вы, кажется, думают, что разветвление делает старт ребенка с самого начала программы. Это не тот случай, разветвление делает ребенка начинаются в одной и той же линии, когда fork() называли

Например посмотрите на этот код здесь:

  read(anon_pipe[0],value_price,100); 

      price+=10; 

      sprintf(value_price,"%d \n",price); 
      printf("Price: %d\n",atoi(value_price)); 

См вы увеличиваете значение price, но вы никогда не читали это значение формирует трубу. Таким образом, все дети всегда будут выводить +10 в соответствующую трубу.

0

Вы должны проверить возвращаемые значения вызовов функций для кодов ошибок. Если вы сделали, вы бы обнаружили ошибку, возникающую из этой комбинации звонков:

  close(anon_pipe[1]); 

      // ... 

      write(anon_pipe[1],value_price,sizeof(value_price)); 

Весьма вероятно, вы также обнаружили, что многие из этих вызовов ...

  read(anon_pipe[0],value_price,100); 

.. . сигнальный конец файла без чтения чего-либо. По крайней мере, вам нужно вернуть значение read(), чтобы определить, где разместить нужный ограничитель строк (который вы не можете разместить перед использованием буфера в виде строки).

Как правило, это обязательного для обработки возвращаемых значений read() и write(), потому что в дополнении к возможности ошибок/EOF, эти функции могут выполнять короткие передачи данных, а не полные. Возвращаемое значение сообщает вам, сколько байтов было передано, что вам нужно знать, чтобы определить, нужно ли цитировать попытку переноса большего количества байтов.

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

Кроме того, не используйте sleep() для синхронизации процессов. Это не работает надежно. Вместо этого родитель должен wait() или waitpid() для каждого из своих дочерних процессов, но только после их запуска и выполнения всей необходимой обработки на конце трубы. Ожидание дочерних процессов также мешает им оставаться зомби в течение какого-либо значительного времени после их выхода. Это не имеет большого значения, когда основной процесс выходит, а не переходит к любой другой работе, как в этом случае, но в противном случае это представляет собой утечку ресурсов (файловые дескрипторы). Вы должны сформировать хорошую привычку ждать своих процессов.

Конечно, все это спорный вопрос, если вы не на самом деле писать данные вы имеете в виду, чтобы написать; @SanchkeDellowar объясняет в своем ответе, как вы этого не делаете.

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

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