【问题标题】:May I send pointers via pipes in the same process, is it safe?我可以在同一进程中通过管道发送指针,它安全吗?
【发布时间】:2014-06-27 03:23:12
【问题描述】:

出于某些原因,我想通过管道发送指针(当然,不是跨进程) 例如,一些数据应该在一切完成后被回收,结构的(指针)通过管道发送到回收线程;或者我想将一些结构从一个工作线程发送到另一个工作线程。在示例中,没有线程可以等待。

那么,我可以通过管道发送指针吗?

考虑以下几点:

  1. 我使用 O_NONBLOCK 向管道写入 8 个字节(例如指针)。但它的缓冲区只剩下 7 个字节。然后从 write() 调用返回“7”。然后其他线程可能会在更多缓冲区可用后写入另一个 8 个字节。当阅读器线程读取管道时,它会得到一个无效的指针。段错误。

  2. 我只发送指向该管道的指针。我读过一些关于管道的文章,我注意到当我写入或读取 8 个字节时,它是一个原子操作。是否确认 (管道的缓冲区大小 % sizeof(void*)) == 0 (或至少在 x86_64 linux 上)?如果是这样,条件(1)会发生吗?

直接发送指针会更快更容易。但是如果不安全的话,我就不得不像UTF-8那样对指针进行编码,或者考虑其他方式。

非常感谢~

【问题讨论】:

  • 我发现没关系。谢谢大家。 man 7 pipe: O_NONBLOCK enabled, n

标签: c multithreading pointers pipe


【解决方案1】:

只要您确保在将缓冲区转换为指针之前接收到 8 个字节,我看不出这技术上有什么问题。做任何编码都没有意义。

但是,当然还有其他更好的方法可以在线程之间传递指针。请注意,使用管道需要对每个 readwrite 进行系统调用(转换到内核模式)。

例如,在共享内存中实现一个队列:

futex(2) 将允许您围绕数据结构实现快速的用户空间锁定(futex 的定义!)。

【讨论】:

  • 谢谢。这是个好办法。但我在管道上使用 epoll :)
  • 要检查的另一件事:使用读取的值时,地址必须仍然有效。在将地址写入管道并期望安全使用它之后,您无法释放内存。
【解决方案2】:

对于管道,小于宏 PIPE_BUF 的值的写入保证是原子的,即它们不能以您关心的方式拆分。所以你的想法是安全的。

【讨论】:

    猜你喜欢
    • 2022-01-01
    • 2018-08-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-20
    • 2020-09-01
    • 2016-03-19
    • 1970-01-01
    相关资源
    最近更新 更多