[问题] 关于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