c - 如何正确关闭管道

标签 c linux pipe

我有一段代码要修改。该代码只是在两个进程(父进程和子进程)之间进行通信的 2 个管道。我正在尝试创建程序的“干净终止”,以便每当从父级向子级发送 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!

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

最佳答案

注意关键变化!

#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;
}

关于c - 如何正确关闭管道,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21471602/

相关文章:

Python 等同于 perl -pe?

c - Qsort导致内存丢失

C 编程 - 套接字 ("Server"在聊天中显示 "Client"名称)

c++ - Ncurses 窗口不显示任何内容

linux - 有没有使用Linux Security Module 的安全软件?

pipe - Windows 在命名管道上轮询或选择

linux - 将 stderr 通过管道传输到自动 ftp 脚本中的 syslog

C - 指向数组 : how to copy just the value (not address) of one pointer to another? 的指针

摄氏度到华氏度的转换总是在摄氏度下显示零

linux - 从 TCP_IN 中删除端口不会将其与 CSF 上的外部流量关闭