【问题标题】:Alternatives to POSIX semaphores for 64-bit/32-bit IPC?64 位/32 位 IPC 的 POSIX 信号量的替代品?
【发布时间】:2019-11-26 21:17:18
【问题描述】:

我需要为需要在 64 位和 32 位进程之间同步的项目实施某种阻塞等待。忙于等待共享内存变量会引入性能/调度问题,并且 POSIX 信号量似乎不支持 32 位和 64 位进程之间的 IPC。 Linux 上的进程间同步还有其他低开销的替代方案吗?

【问题讨论】:

  • 你也许可以用std::atomic<uint32_t> 做一些事情,或者类似的事情。忘记使用比这更复杂的东西,比如std::mutex,因为你不能保证它在 32 位和 64 位代码之间兼容。对于简单的用例,简单的文件锁定方法也可能有效。
  • 我曾考虑过文件锁定,但担心文件 I/O 开销。我还认为 C++11 std::atomic 仅用于 线程 之间的通信,而不是进程之间的通信。
  • 您对“共享内存”的引用意味着像std::atomic 这样的东西将是一个选项。就文件锁定而言,实际磁盘 I/O 的可能性非常小,因为所有操作都将在缓冲内存中执行。编写一个循环来重写同一个文件,一千次包含几个字节。看看有多少磁盘活动实际上是由此产生的。
  • 传统管道或 UNIX 套接字怎么样?
  • 既然你在 Linux 上,你应该考虑Unix domain sockets。我知道它们比管道略快。

标签: c++ c linux ipc semaphore


【解决方案1】:

对于使用阻塞等待的进程间同步,简单的解决方案包括named pipe (fd)System V Semaphore

Named pipes 有一个与之关联的文件路径,以便两个进程可以独立打开文件(一个用于读取,另一个用于写入)。对于纯同步,只需putc() 发出信号,getc() 等待,一次一个字符(值无关紧要)。这将创建一个单向(“半双工”)通道;对于双向信号/等待,您将创建两个文件。您甚至可以通过连续执行多个putc() 调用来排队多个信号,有点像永不饱和的信号量。

System V Semaphores 也有一个与之关联的文件路径。它们的行为类似于 Dijkstra 信号量。

有关其他选项,请查看

https://en.wikipedia.org/wiki/Inter-process_communication

【讨论】:

    【解决方案2】:

    Linux 有futexes,这是一个内核原语,它为一个进程进入睡眠状态和另一个进程唤醒它提供了一种方式。它们有非常好的快速路径(在这些情况下避免内核调用),如果您将它们用作互斥体,这很重要,但如果您将它们用作信号量,则无关紧要。

    您只需要它的两个最原始的功能。一个,FUTEX_WAIT,当且仅当共享内存中的特定条目具有特定值时,才使内核进入睡眠状态。另一个,FUTEX_WAKE,用 FUTEX_WAIT 唤醒一个已经进入睡眠状态的进程。

    您的“等待”代码会自动检查共享变量以查看它是否需要休眠,然后当且仅当共享变量没有更改时调用 FUTEX_WAIT 进入休眠状态。您的“唤醒”代码将更改原子共享变量的值,然后调用 FUTEX_WAKE 唤醒任何正在休眠的线程。

    如果您使用 64 位共享变量,但仅将有意义的数据放在前 32 位中,那么 32 位/64 位问题根本不重要,因此无论作为 64 位处理,它都可以正常工作变量或 32 位变量。

    【讨论】:

      猜你喜欢
      • 2011-08-17
      • 2017-04-14
      • 1970-01-01
      • 2011-11-19
      • 2012-10-26
      • 1970-01-01
      • 2012-02-20
      • 1970-01-01
      • 2011-01-17
      相关资源
      最近更新 更多