2011-05-10 90 views
1

我想使用Boost库同步两个线程(在相同的C++映射上工作)。我必须告诉我,我不是C++的专家,我觉得boost文档很难理解。C++:线程同步

我想实现什么,是这样的:

#Thread 1 
get access to the map 
put in something 
release access 

#Thread 2 
wait until map is empty 
when it's not empty anymore, wake up and gain access 
perform operations on one entry of the map 
leave access to somebody else 

我试图用互斥和condition_variables,但代码不能正常工作。具体来说,当thread2在唤醒时(在等待cond变量之后),它不能直接访问地图,但有其他人访问并清空了地图。因此,我得到了分段错误,因为我期待地图充满,而当我访问它时它是空的。

此外,我想了解类似mymutex.lock()和类似boost::mutex::scoped_lock scopedLock(mutex_)之类的调用之间的区别; 或unique_lock

感谢教学:)

编辑:在这里我想提取我的代码的相关部分。由于我没有很明白如何同步工作,它可能没有多大意义......

//COMMON PART 
boost::mutex mutex1; 
boost::mutex mutex2; 
boost::condition_variable cond; 
boost::mutex::scoped_lock mutex2lock(mutex2); 

//THREAD 1 
... 
if(someCondition){ 
    mutex1.lock(); 
    map[id]=message; 
    cond.notify_one(); 
    mutex1.unlock(); 
} 
... 


//THREAD 2 
... 
cond.wait(mutex2lock); 
mutex.lock(); 
//Perform operation on map[id] 
doSomething(map[id])); 
mutex.unlock(); 
... 
+2

给我们看一些代码。 – 2011-05-10 19:50:17

+1

你应该在实际的线程正在做的事上添加一些代码。当thread2醒来时它不能直接访问映射* ...很难调试* ...您的描述似乎表明有一个生产者和一个消费者,这不会解释*其他人清空地图*。只有2个线程?他们真的在分享地图吗? – 2011-05-10 19:59:18

+0

是的,他们真的是共享地图,这是一种容器。这两个线程都可以放/取东西。有时候发生的事情是thread1一个接一个地访问两次。它第一次放置了一些东西。与此同时,thread2会因为看到通知而醒来。但是,在线程2继续之前,线程1会再次执行,并且这次它将输入出地图。对不起,因为在解释中如此混乱,我希望这已经足够清楚了:P – Danilo 2011-05-10 20:02:40

回答

1
boost::mutex::scoped_lock mutex2lock(mutex2); 

这应该,如果我理解正确,但对互斥锁2的一个大锁将持续您的互斥锁的长度。

可能你想在第二个线程的上下文中使用该锁,但我不太明白为什么condition_variable需要它。

事实上,似乎condition_variable本身是有点错了,你在做什么,阅读文档:

以原子呼叫lock.unlock(),并阻塞当前线程。当通过调用这个 - > notify_one(通知线程将解锁)或这个 - > notify_all(),或不合逻辑的

这说明在我看来,当它认为它可以运行它可以直接解锁(可能基于时间)看起来您可能需要检查列表是否有效,如果不是,请再次调用wait,如果您打算使用condition_variable。

+0

感谢您的提示!问题与您所描述的完全相同。线程2等待地图是“有效的”(不是空的)。当它有效时,它必须继续确定地图中有东西。 – Danilo 2011-05-11 05:47:59

2

此外,我想了解 像mymutex.lock之间的差异()和 invoations like boost :: mutex :: scoped_lock scopedLock(mutex_);或unique_lock。

谷歌为 “C++ RAII”:

随着mymutex.lock()你是 “手动” 锁定互斥。 (后来必须“手动”解锁。)

scoped_lock是一个帮助类,它在您的作用域结束时进行锁定并自动解锁。