Linux / Unix中的futex是否有任何等价物?
我在C / C ++中寻找可用于轮询的东西(如select
, kqueue
, epoll
即不繁忙的轮询 )。 换句话说,我需要阻塞一个线程,然后在尽可能少的开销中将其唤醒到另一个线程中。
mutex
+ condition variable
有效,但是有很多开销。 一个futex
也可以,但那只适用于Linux(或许不是?)。 只要轮询本身正常工作,就不需要额外同步,例如,当我在两个线程中调用wait
和wake
时没有竞争。
编辑:如果FreeBSD中不存在这样的“工具”,如何使用C ++ 11内置类型和系统调用创建一个?
Edit2:由于这个问题被迁移到了SO,我想让它更通用(不仅仅适用于FreeBSD)
信号量不是互斥量,并且可以稍微减少开销(例如,避免互斥锁+ condvar重新锁定)
请注意,由于线程在被唤醒之前hibernate的任何解决方案都涉及内核系统调用,因此它仍然不便宜 。 假设x86_64 glibc和FreeBSD libc都是合理的实现,那么不可避免的成本似乎是:
- 用户模式同步计数(使用CAS或类似)
- 内核管理等待队列和线程睡眠/等待
我假设您担心的互斥+ + condvar开销是cond_wait-> re-lock-> unlock序列,这在这里确实可以避免。
你想要信号量而不是互斥量来获取线程之间的信号。
http://man7.org/linux/man-pages/man3/sem_wait.3.html
信号量可以像计数器一样使用,例如,如果你有一个队列,每次插入一条消息时你都会递增(post)到信号量,你的接收者会在信号量上减去(等待)每条消息。 如果计数器达到零,接收器将阻塞,直到发布某些内容。
所以一个典型的模式就是将互斥量和信号量结合起来;
sender: mutex.lock insert message in shared queue mutex.unlock semaphore.post receiver: semaphore.wait mutex.lock dequeue message from shared structure mutex.unlock