我正在寻找可以用于投票的内容(例如select
,kqueue
,epoll
,即忙碌轮询)在C / C ++中。换句话说,我需要阻塞一个线程,然后在另一个线程中使用尽可能少的开销将其唤醒。
mutex
+ condition variable
有效,但会有很多开销。 futex
也可以,但这只适用于Linux(或许不是?)。只要轮询本身正常工作,就不需要额外的同步,例如,我在两个主题中调用wait
和wake
时没有竞争。
编辑:如果FreeBSD中不存在这样的“工具”,如何使用C ++ 11内置类型和系统调用创建一个?
Edit2:由于这个问题被迁移到了SO,我想让它更通用(不仅适用于FreeBSD)
答案 0 :(得分:3)
信号量不是互斥量,并且可以稍微减少开销(例如,避免使用互斥锁+ condvar重新锁定)
请注意,由于线程在被唤醒之前休眠的任何解决方案都涉及内核系统调用,因此它仍然不是便宜。假设x86_64 glibc和FreeBSD libc都是合理的实现,那么不可避免的成本似乎是:
我认为你担心的互斥+ + condvar开销是cond_wait-> re-lock->解锁序列,这在这里确实可以避免。
答案 1 :(得分:2)
你想要信号量而不是互斥量来获取线程之间的信号..
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