2011-05-10 102 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是一個幫助類,它在您的作用域結束時進行鎖定並自動解鎖。