C 0x是否会没有信号量? Stack Overflow上已经有一些关于信号量使用的问题 . 我一直使用它们(posix信号量)让线程等待另一个线程中的某个事件:
void thread0(...)
{
doSomething0();
event1.wait();
...
}
void thread1(...)
{
doSomething1();
event1.post();
...
}
如果我用互斥量做到这一点:
void thread0(...)
{
doSomething0();
event1.lock(); event1.unlock();
...
}
void thread1(...)
{
event1.lock();
doSomethingth1();
event1.unlock();
...
}
问题:它很难看并且不能保证thread1首先锁定互斥锁(假设同一个线程应该锁定和解锁互斥锁,你也无法在thread0和thread1启动之前锁定event1) .
因此,由于boost也没有信号量,实现上述目标的最简单方法是什么?
9 回答
根据posix信号量,我想补充一下
而且我更喜欢在方便的抽象级别使用同步机制,而不是总是使用更基本的运算符复制粘贴拼接在一起的版本 .
您还可以查看cpp11-on-multicore - 它具有可移植的最佳信号量实现 .
存储库还包含补充c 11线程的其他线程好东西 .
您可以使用互斥锁和条件变量 . 您可以使用互斥锁获得独占访问权限,检查是否要继续或需要等待另一端 . 如果你需要等待,你就等待 . 当另一个线程确定您可以继续时,它会发出条件信号 .
boost :: thread库中有一个简短的example,你最有可能只是复制(C 0x和boost线程库非常相似) .
您可以使用互斥锁和条件变量轻松构建一个:
基于Maxim Yegorushkin's answer,我尝试用C 11风格制作示例 .
我决定尽可能地以标准的风格编写最强大/通用的C 11信号量(注意
using semaphore = ...
,你通常只使用名称semaphore
,类似于通常使用string
而不是basic_string
):也可以在线程中使用RAII信号量包装器:
多线程应用程序中的用法示例:
我发现shared_ptr和weak_ptr,一个带有列表的long,完成了我需要的工作 . 我的问题是,我有几个客户希望与主机的内部数据进行交互 . 通常,主机会自行更新数据,但是,如果客户端请求数据,主机需要停止更新,直到没有客户端访问主机数据 . 同时,客户端可以请求独占访问权限,这样任何其他客户端和主机都无法修改该主机数据 .
我是怎么做到的,我创建了一个结构:
每个客户都有这样的成员:
然后主机将拥有一个独占的weak_ptr成员,以及一个非独占锁的weak_ptrs列表:
有一个启用锁定的功能,另一个功能是检查主机是否被锁定:
我在LockUpdate,IsUpdateLocked中测试锁定,并在主机的Update例程中定期测试 . 测试锁定就像检查weak_ptr是否过期一样简单,并从m_locks列表中删除任何过期(我只在主机更新期间执行此操作),我可以检查列表是否为空;同时,当客户端重置挂起的shared_ptr时,我会自动解锁,当客户端被自动销毁时也会发生这种情况 .
最重要的是,由于客户端很少需要排他性(通常只保留用于添加和删除),因此大多数情况下对LockUpdate(false)的请求(即非排他性)只要(!m_exclusiveLock)成功 . LockUpdate(true)是一种排他性请求,只有在(!m_exclusiveLock)和(m_locks.empty())都成功时才会成功 .
可以添加一个队列来缓解独占锁和非独占锁,但是,到目前为止我没有碰撞,所以我打算等到发生这种情况时才添加解决方案(主要是因为我有一个真实的测试条件) .
到目前为止,这对我的需求很有效;我可以想象扩展它的必要性,以及可能因扩展使用而出现的一些问题,但是,这很快实现,并且需要很少的自定义代码 .
如果有人对原子版感兴趣,这里是实现 . 预计性能优于互斥和条件变量版本 .