[問題] 關於std::mutex的應用

作者: icetofux   2020-04-28 06:26:40
開發平台(Platform): (Ex: Win10, Linux, ...)
Win10/Linux
編譯器(Ex: GCC, clang, VC++...)+目標環境(跟開發平台不同的話需列出)
GCC
額外使用到的函數庫(Library Used): (Ex: OpenGL, ...)
None
問題(Question):
最近在使用C++11的std::thread,我已經知道若要在不同的thread存取同一個變數,
必須使用mutex來做管理才能達到Thread-Safe。
目前遇到的問題是,若我有多個不同的變數分別必須在多個不同的thread內存取,我
除了變數名稱外,還必須一一產生對應的mutex,我想建立下列這樣的樣板類別:
template <class T>
class SharedVariable {
private:
std::mutex mtx;
T data;
public:
T Get(void) {
T data_cpy;
std::lock_guard<std::mutex> lck(mtx);
data_cpy = this->data;
return data_cpy;
}
void Set(const T data) {
std::lock_guard<std::mutex> lck(mtx);
this->data = data;
}
};
在產生變數物件的同時,該物件也同時具有一個不用額外命名的mutex,並且當我
透過Get/Set存取變數時,也自動做好了上鎖、解鎖的功能。
SharedVariable<int> shared_int;
SharedVariable<std::string> shared_string;
SharedVariable<std::vector<double>> shared_vector;
shared_int.Set(123);
int a = shared_int.Get();
目前比較讓我有疑慮的是,在不同的thread內使用物件本身(如上例的shared_int、
shared_string、shared_vector)是一個Thread-Safe的行為嗎?我不確定要如何判
斷,想請有經驗的先進指教。
謝謝。
餵入的資料(Input):
None
預期的正確結果(Expected Output):
None
錯誤結果(Wrong Output):
None
程式碼(Code):(請善用置底文網頁, 記得排版,禁止使用圖檔)
None
補充說明(Supplement):
作者: loveme00835 (髮箍)   2020-04-28 07:43:00
或者你應該思考的是: 為什麼多個執行緒都可以去更改同個物件的狀態, 而不是讓單個專責的執行緒來做呢?可以參考看看 active object pattern 把兩者先鬆綁
作者: icetofux   2020-04-28 15:45:00
我的程式由9個thread構成,8個各自跑不同的流程,透過socket與不同設備通訊,1個負責GUI,把8個設備的細部資料顯示出來,每個設備約有60多種的細部資料。文中所提在thread間共用的變數就是設備傳輸至GUI的細部資料。謝謝loveme00835,我剛剛google了active object pattern,好像就是用來避免大量mutex的設計模式,雖然沒把握馬上帶入應用,但是一個可以努力的方向。
作者: eye5002003 (下一夜)   2020-04-28 17:47:00
這情況不是用std::atomic比較適合嗎?
作者: Lipraxde (Lipraxde)   2020-04-28 19:56:00
一般不是保護 critical section 嗎?每個變數都給一個mute lock 好像比較少看到mute -> mutex
作者: kobe8112 (小B)   2020-04-28 19:59:00
如果改成各設備更新的資料丟到各自的queue中,UI更新的Thread輪詢各queue是否有資料需更新呢?
作者: loveme00835 (髮箍)   2020-04-27 23:43:00
或者你應該思考的是: 為什麼多個執行緒都可以去更改同個物件的狀態, 而不是讓單個專責的執行緒來做呢?可以參考看看 active object pattern 把兩者先鬆綁
作者: icetofux   2020-04-28 07:45:00
我的程式由9個thread構成,8個各自跑不同的流程,透過socket與不同設備通訊,1個負責GUI,把8個設備的細部資料顯示出來,每個設備約有60多種的細部資料。文中所提在thread間共用的變數就是設備傳輸至GUI的細部資料。謝謝loveme00835,我剛剛google了active object pattern,好像就是用來避免大量mutex的設計模式,雖然沒把握馬上帶入應用,但是一個可以努力的方向。
作者: eye5002003 (下一夜)   2020-04-28 09:47:00
這情況不是用std::atomic比較適合嗎?
作者: Lipraxde (Lipraxde)   2020-04-28 11:56:00
一般不是保護 critical section 嗎?每個變數都給一個mute lock 好像比較少看到mute -> mutex
作者: kobe8112 (小B)   2020-04-28 11:59:00
如果改成各設備更新的資料丟到各自的queue中,UI更新的Thread輪詢各queue是否有資料需更新呢?
作者: sarafciel (Cattuz)   2020-04-28 13:53:00
https://ideone.com/wHfCXi 拿你的模板寫了一小段應該很容易看出問題才是
作者: steak5566 (牛排56)   2020-04-28 22:55:00
可以請樓上大大可以解說一下為什麼嗎
作者: Caesar08 (Caesar)   2020-04-29 13:37:00
sarafciel的strt_flag型態要改成atomic<bool>另外,func與func2不相等,func保護的是整段過程func2只保護每次sv_int的read write結果不一樣是正常的你的Get直接return data_cpy就好,不用先create再copy另外有支援C++ 17的話,用shared_mutex會比mutex好
作者: steve1012 (steve)   2020-04-29 14:04:00
不是有鎖住就好 還要看你想保護的東西是什麼 比如說你各個function 之間有沒有什麼順序先後需要保證的muli threading 寫的越簡單通常越好 容易看出有沒有問題
作者: ucrxzero (RX-0)   2020-04-30 18:11:00
嗯嗯

Links booklink

Contact Us: admin [ a t ] ucptt.com