64位/32位IPC使用的替代POSIX信号量的方法?

3

我需要实现一种阻塞等待方法,以实现在64位和32位进程之间进行同步。 使用对共享内存变量的忙等待会引入性能/调度问题,而POSIX信号量似乎不支持32位和64位进程之间的IPC。在Linux上是否有其他低开销的进程间同步替代方法?


你可以尝试使用std::atomic<uint32_t>或类似的方法来解决问题。不要使用比这更复杂的东西,例如std::mutex,因为无法保证其在32位和64位代码之间兼容。对于简单的用例,简单的文件锁定方法也可能有效。 - Sam Varshavchik
我曾考虑过文件锁定,但担心会增加文件I/O开销。同时我也认为C++11的std::atomic只用于线程间通信,而非进程间通信。 - techguy227
你对“共享内存”的提及意味着std::atomic之类的选项可以使用。至于文件锁定,实际磁盘I/O的机会相当小,因为所有操作将在缓冲内存中执行。编写一个循环来重写同一个文件,包含几个字节一千次。看看实际产生了多少磁盘活动。 - Sam Varshavchik
2
传统的管道或UNIX套接字怎么样? - Jonathon Reinhart
由于您正在使用Linux,您应该考虑使用Unix域套接字。我了解到它们比管道略快。 - jww
2个回答

1

Linux有futexes,它们是内核原语,提供了一种让一个进程休眠并让另一个进程唤醒它的方法。如果将它们用作互斥锁,则具有极好的快速路径(在这些情况下避免了内核调用),这很重要,但如果将它们用作信号量,则不太重要。

你只需要它的两个最原始的函数。其中一个FUTEX_WAIT,只有在共享内存中的特定条目具有特定值时,才会使内核休眠。另一个函数FUTEX_WAKE,唤醒使用FUTEX_WAIT进入休眠状态的进程。

你的“等待”代码会原子地检查共享变量以查看是否需要休眠,然后调用FUTEX_WAIT进入休眠状态,仅当共享变量未更改时。你的“唤醒”代码将更改原子共享变量的值,然后调用FUTEX_WAKE来唤醒任何处于休眠状态的线程。

如果您使用64位共享变量但仅在前32位中放置有意义的数据,则32位/64位问题将完全无关紧要,因此无论是寻址为64位变量还是32位变量,它都可以正常工作。


0

对于使用阻塞等待进行进程间同步,简单的解决方案包括命名管道(fd)System V 信号量

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

System V 信号量也与文件路径相关联。 这些表现类似于Dijkstra信号量。

有关其他选项,请查看

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接