如何正确关闭管道

时间:2014-01-31 02:50:15

标签: c linux pipe

我想要改变一段代码。代码只是两个管道,它们在两个进程(父进程和子进程)之间进行通信。我正在尝试创建程序的“清理终止”,以便每当从父级向子级发送0时,相应的进程将关闭所有管道的末尾。

代码如下:

int main
{
   int pipe1[2], pipe2[2], value, request;
   if(pipe(pipe1) < 0 || pipe(pipe2) < 0)
        printf("Failed to create pipes.\n");

   switch(fork())
   {
       case -1:
            perror("Cannot create fork.\n");
            break;

       case 0:
           close (pipe1[WRITE]);
           close (pipe2[READ]);
           close (0);
           close (1);

         for(;;) {
           read(pipe1[READ], &value, sizeof value);

           //If user enters 0.
           if(value == 0)
           {
               printf("Terminating child process!\n");
               close(pipe1[READ]);
               //write a 0 back to the parent so that it can close its end.
               write(pipe2[WRITE], 0, sizeof (int));
               close(pipe2[WRITE]);
               exit(0);
           }
           else
           {
               /*Enter function to do something on the number here*/
               write(pipe2[WRITE], &result, sizeof result);
           }
        }
        break;

        default: /* PARENT PROCESS - PRODUCER */
             close(pipe1[READ]);
             close(pipe2[WRITE]);
             for(;;) {
                 printf("Ange ett tal: ");
                 scanf("%d", &value);
                 if(write(pipe1[WRITE], &value, sizeof value) != sizeof value)
                 {
                     perror("Cannot write thru pipe.\n");
                     return 1;
                 }

             //Clean shutdown if value == 0
              if(value == 0)
             {
                 close(pipe2[WRITE]);
                 read(pipe2[READ],&result,sizeof(result));
                 if(result == 0)
                 {
                     close(pipe2[READ]);
                     printf("Pipe2[Read] closed!\n");
                     wait(0);
                 }
             }

             else
             {
                 read(pipe2[READ],&result,sizeof(result));
                 printf("Result: %d.\n",result);
             }

     }
     break;
  }


}

我已经在这几个小时了,我不明白为什么我的代码都是疯狂的。当我输入1时,它显示“管道已关闭,如果我输入0,它会在发出错误Cannot create pipes!之前尝试接受另一个输入。

我想我在这里缺少一些非常基本的东西。非常感谢任何有关该主题的帮助。

1 个答案:

答案 0 :(得分:0)

注意关键变化!

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>

enum { READ = 0, WRITE = 1 };

int main(void)
{
    int pipe1[2], pipe2[2], value, result;
    if (pipe(pipe1) < 0 || pipe(pipe2) < 0)
        printf("Failed to create pipes.\n");

    switch (fork())
    {
    case -1:
        perror("Cannot create fork.\n");
        break;

    case 0:
        close(pipe1[WRITE]);
        close(pipe2[READ]);

        while (read(pipe1[READ], &value, sizeof(value)) > 0)
        {
            // If user enters 0.
            if (value == 0)
            {
                printf("Terminating child process!\n");
                close(pipe1[READ]);
                // write a 0 back to the parent so that it can close its end.
                write(pipe2[WRITE], 0, sizeof(int));
                close(pipe2[WRITE]);
                exit(0);
            }
            else
            {
                result = value + 1;
                write(pipe2[WRITE], &result, sizeof result);
            }
        }
        break;

    default:     /* PARENT PROCESS - PRODUCER */
        close(pipe1[READ]);
        close(pipe2[WRITE]);
        for ( ; ; )
        {
            printf("Ange ett tal: ");
            if (scanf("%d", &value) != 1)
                break;
            if (write(pipe1[WRITE], &value, sizeof(value)) != sizeof(value))
            {
                perror("Cannot write thru pipe.\n");
                return 1;
            }
            // Clean shutdown if value == 0
            if (value == 0)
            {
                close(pipe1[WRITE]);    // Key change!
                if (read(pipe2[READ], &result, sizeof(result)) <= 0 || result == 0)
                {
                    close(pipe2[READ]);
                    printf("Pipe2[Read] closed!\n");
                    wait(0);
                    break;
                }
            }
            else
            {
                if (read(pipe2[READ], &result, sizeof(result)) <= 0)
                    break;
                printf("Result: %d.\n", result);
                if (result == 0)
                {
                    printf("Read zero - exit\n");
                    close(pipe1[WRITE]);
                    close(pipe2[READ]);
                    break;
                }
            }
        }
        break;
    }

    return 0;
}