我正在使用C++ boost::thread库,就我而言,这意味着我正在使用pthreads。正式地,互斥锁必须从锁定该线程的同一线程中解锁,我希望能够锁定一个线程然后在另一个线程中解锁的效果。有很多方法可以完成此任务。一种可能性是编写一个允许这种行为的新互斥体类。
例如:
class inter_thread_mutex{
bool locked;
boost::mutex mx;
boost::condition_variable cv;
public:
void lock(){
boost::unique_lock<boost::mutex> lck(mx);
while(locked) cv.wait(lck);
locked=true;
}
void unlock(){
{
boost::lock_guard<boost::mutex> lck(mx);
if(!locked) error();
locked=false;
}
cv.notify_one();
}
// bool try_lock(); void error(); etc.
}
我应该指出,上面的代码不能保证FIFO访问,因为如果一个线程调用lock()而另一个线程调用unlock(),则第一个线程可能会在其他正在等待的线程之前获取锁。 (来想一想,boost::thread文档似乎并没有为互斥量或条件变量做出任何明确的调度保证)。但是,让我们暂时忽略它(以及所有其他错误)。
我的问题是,如果我决定走这条路,我能否将这种互斥锁用作增强型可锁定概念的模型。例如,如果我使用
boost::unique_lock< inter_thread_mutex >
进行RAII风格的访问,然后将此锁传递给boost::condition_variable_any.wait()
,那么会出错吗?一方面,我不明白为什么不这样做。另一方面,“我不明白为什么不这样做”通常是确定某项内容是否可行的非常糟糕的方法。
我问的原因是,如果事实证明我必须为RAII锁和条件变量以及其他内容编写包装器类,那么我宁愿找到其他方法来实现相同的效果。
编辑:
我想要的行为基本上如下。我有一个对象,只要修改它就需要将其锁定。我想从一个线程中锁定对象,并对其进行一些工作。然后,当我告诉另一个工作线程完成工作时,我想保持对象锁定。因此,在工作线程完成时,第一个线程可以继续执行其他操作。工作线程完成后,它将解锁互斥锁。
而且我希望这种过渡看起来很平稳,这样当线程1开始工作而线程2完成工作时,没人能在两者之间获得互斥锁。
诸如inter_thread_mutex之类的东西似乎可以工作,并且还允许该程序与它进行交互,就好像它是普通的互斥锁一样。因此,这似乎是一个干净的解决方案。如果有更好的解决方案,我也很高兴听到。
再次编辑:
我之所以需要锁,是因为有多个主线程,并且那里的锁可以防止它们以无效方式并发访问共享对象。
因此,代码已经在主线程级别使用了循环级别的无锁操作序列。另外,在原始实现中,没有工作线程,并且互斥锁是普通的洁食互斥锁。
inter_thread_thingy是一项优化,主要是为了缩短响应时间。在许多情况下,足以保证操作A的“第一部分”出现在操作B的“第一部分”之前。举个愚蠢的例子,我对对象1进行打孔,然后给它黑眼睛。然后,我告诉对象1更改其内部结构以反射(reflect)所有组织损伤。我不想在继续对物体2进行打孔之前等待组织损伤。但是,我确实希望组织损伤是在同一操作中发生的;因此,我希望对组织进行损伤。例如,在此期间,我不希望任何其他线程重新配置该对象,从而使组织损坏成为无效操作。 (是的,这个示例在许多方面都不完美,不,我不是在玩游戏)
因此,我们对模型进行了更改,在该模型中,对象的所有权可以传递给工作线程以完成操作,并且实际上效果很好。每个主线程能够完成更多的操作,因为它不需要等待它们全部完成。而且,由于主线程级的事件排序仍基于循环,因此编写高级主线程操作很容易,因为它们可以基于操作已完成的假设(更确切地说,关键的“当相应的函数调用返回时,排序逻辑所依赖的“第一部分”就完成了。
最后,我认为最好将带有RAII的inter_thread互斥体/信号量东西与boost锁一起使用,以封装使整个东西正常工作所需的必要同步。
最佳答案
man pthread_unlock
(在OS X上,类似于Linux上的措辞)具有答案:
名称
pthread_mutex_unlock-解锁互斥锁
概要
#include
整型
pthread_mutex_unlock(pthread_mutex_t * mutex);
描述
如果当前线程持有互斥锁,则
pthread_mutex_unlock()函数可解锁互斥锁。
使用互斥锁调用pthread_mutex_unlock()
调用线程不成立将导致
未定义的行为。
...
我的反问是-您试图以此解决哪种同步问题?很可能有一个更简单的解决方案。pthreads
和boost::thread
(在其顶部构建)都不能保证竞争线程获取竞争互斥体的任何顺序。
关于c++ - 对boost::: Model进行建模,可以使用信号灯而不是互斥锁(以前的标题:从其他线程解锁互斥锁),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2754884/