【问题标题】:Is there any difference between socketpair and pair of unnamed pipes?socketpair 和一对未命名的管道有什么区别吗?
【发布时间】:2010-12-07 16:02:13
【问题描述】:

我不仅想知道用户方面的差异,还想知道 Linux 内核实现中的差异/共同部分。

【问题讨论】:

    标签: sockets linux-kernel pipe


    【解决方案1】:
    • 管道是单向的,因此您需要两个管道进行双向通信,而套接字对是双向的。

    • 管道始终是面向流的,而套接字对可以是面向数据报的。

    • socketpairs 是普通的AF_UNIX 套接字,这意味着可以通过它们传递诸如SCM_RIGHTSSCM_CREDENTIALS 之类的辅助消息。

    在内核中,管道在文件系统代码中实现,套接字对在网络代码中实现。

    【讨论】:

    • 我认为套接字对也支持部分读取,而管道不支持。
    【解决方案2】:

    需要套接字对的shutdown()SCM_RIGHTS 功能来实现与多线程程序中的子进程的防竞争通信。

    如果多个线程pipe()fork()同时出现,管道可能会被意外复制;在这种情况下,管道的写入端可能永远不会关闭,而读取端可能永远不会发生 EOF,从而导致死锁。即使对于那些仅将fork() 用于子进程的程序(即所有fork()s 都紧跟在子进程中的execve()),并发fork() 的管道捕获仍然与设置FD_CLOEXEC 位竞争,除非使用接受 O_CLOEXEC 的非便携式 Linux pipe2() 系统调用。

    以一种可移植的方式解决这个危险,也适用于 fork() 而不调用 execve() 的程序,涉及套接字对:

    • 对于出站通道(即,从主程序写入子进程):使用套接字对而不是管道,并在父级的 close() 之前调用 shutdown() 以导致竞争证明 EOF 条件,无论文件描述符是否重复。
    • 对于入站通道(即从子进程读取),在子进程中创建一个管道(这样在父进程中写入端永远不可见,以防意外复制)并通过套接字对仅将读取端发送到父进程SCM_RIGHTS 消息。

    【讨论】:

      猜你喜欢
      • 2011-11-03
      • 1970-01-01
      • 2018-08-25
      • 2015-07-11
      • 2021-05-08
      • 2013-09-05
      • 2020-03-21
      • 2015-02-02
      相关资源
      最近更新 更多