【问题标题】:Creating Bidirectional Pipe in C For Both Reading and Writing Using One Pipe (Linux)在 C 中创建双向管道以使用一个管道进行读取和写入 (Linux)
【发布时间】:2020-08-01 20:24:21
【问题描述】:

是否可以使用一个管道在进程之间进行读写?我的伪代码很像下面。我试过了,但它给了我一个错误,说“错误的文件描述符”。

create fd[2]
create pipe(fd)

parent:
     close fd[0]
     write something to fd[1]
     close fd[1]
     // wait for child's signal
     close fd[1]
     read the response fd[0]
     close fd[0]

child:
     close fd[1]
     read the pipe fd[0]
     close fd[0]

    // write an answer to the parent via the existing pipe
    // no need to close fd[0], since it's already closed
     write the answer fd[1]
     close fd[1]
     signal to the parent

非常感谢。

【问题讨论】:

    标签: c process pipe fork ipc


    【解决方案1】:

    当您关闭文件描述符时,您将无法再使用它。
    管道是单向的;在许多应用程序中,您只需决定 在您的两个进程之间,哪个是读者,哪个 一位将成为作家。
    但是通过特定的同步,您可以交换这两个角色 正如您的示例中所建议的那样(请参阅下面的编辑)。

    如果需要双向流,可以使用socketpair(PF_LOCAL, SOCK_STREAM, 0, fd)


    编辑,关于关闭不要太早

    当您确定时,只需关闭管道的一端 您的流程将不再需要它。

    只是不要期望在 同步信号,因为管道的另一端没有 关门了。

    这个例子可能会有所帮助。

    #!/usr/bin/env python
    
    import sys
    import os
    import signal
    
    fd=os.pipe()
    p=os.fork()
    if p==0:
      signal.signal(signal.SIGUSR1, lambda signum, frame: 0)
      os.write(fd[1], b'A')
      os.close(fd[1]) # I will never write again to this pipe
      signal.pause() # wait for the signal before trying to read
      b=os.read(fd[0], 1)
      os.close(fd[0]) # I will never read again from this pipe
      sys.stdout.write('child got <%s>\n'%b)
    else:
      a=os.read(fd[0], 1)
      os.close(fd[0]) # I will never read again from this pipe
      sys.stdout.write('parent got <%s>\n'%a)
      os.kill(p, signal.SIGUSR1) # now the child is allowed to read
      os.write(fd[1], b'B')
      os.close(fd[1]) # I will never write again to this pipe
      os.wait()
    

    【讨论】:

    • 这是一个家庭作业,我们只能使用 pipe、dup、fork。我读了一些关于为此使用 dup2 的内容。但他们都将它用于标准输出和标准输入。我们可以使用 dup2 来达到这个目的吗?
    • 那么,既然我使用信号进行同步,它应该可以工作吗?使用这样的管道没有问题。如果这是正确的,那么肯定还有另一个错误。谢谢。
    • @Taylor “像这样” 没有。一旦你关闭了一个文件描述符,你就不能再使用它了。
    • 管道是单向的,因为有一个专门用于写入的末端和一个专门用于读取的末端,但不是(技术上)只有一个进程可以写入到给定的管道或只有一个人可以从该管道读取。
    • 这太可怕了。我喜欢它。
    【解决方案2】:

    是否可以使用一个管道在进程之间同时读写?

    从技术上讲,是的,两个进程可以使用单个管道进行双向通信。管道本身没有特殊要求来启用此功能,但每个进程必须让每个管道端打开,只要他们想使用该端(与您的伪代码相反)。不过要明确一点:管道有一个写端和一个读端。对管道的所有写入都必须到写入端,并且所有读取都必须在读取端执行,但多个进程可以使用每一端。

    但是以这种方式使实际的双向通信正常工作是非常棘手的,因为任何写入管道的数据都可以被任何打开读取端的进程读取,包括写入它的进程(尽管只有一个进程会实际读取每个字节),并且因为只要 any 进程打开写入端,就没有进程会在管道的读取端观察到文件结束信号。因此,要双向使用单个管道,您需要一些额外的 IPC 机制在通信进程之间进行调解,以确保每个进程都收到完整的消息,消息不会混合在一起,并且如果适用,每个进程只接收定向的消息给它。

    为每对通信进程设置两个管道要容易得多,每个方向一个。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-11-04
      • 2019-11-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-01-15
      • 1970-01-01
      相关资源
      最近更新 更多