Joe*_*res 6 c++ multithreading mutex c++11
假设我有一个类代表一些名为 foo 的数据结构:
\n\nclass foo{\n public:\n foo(){\n attr01 = 0;\n }\n void f(){\n attr01 += 5;\n }\n private:\n int attr01;\n};\n\nclass fooSingleThreadUserClass{\n void usefoo(){\n fooAttr.f();\n }\n\n foo fooAttr;\n}\nRun Code Online (Sandbox Code Playgroud)\n\n现在假设在软件构建的后期,我发现我需要多线程。我应该在 foo 中添加互斥体吗?
\n\nclass foo{\n public:\n foo(){\n attr01 = 0;\n }\n void f(){\n attr01Mutex.lock();\n attr01 += 5;\n attr01Mutex.unlock();\n }\n private:\n int attr01;\n std::mutex attr01Mutex;\n};\n\nclass fooMultiThreadUserClass{\n void usefoo(){\n std::thread t1(&fooMultiThreadUserClass::useFooWorker, this);\n std::thread t2(&fooMultiThreadUserClass::useFooWorker, this);\n std::thread t3(&fooMultiThreadUserClass::useFooWorker, this);\n std::thread t4(&fooMultiThreadUserClass::useFooWorker, this);\n\n t1.join();\n t2.join();\n t3.join();\n t4.join();\n }\n\n void useFooWorker(){\n fooAttr.f();\n }\n\n foo fooAttr;\n}\nRun Code Online (Sandbox Code Playgroud)\n\n我知道 fooMultiThreadUserClass 现在能够在没有竞争的情况下以高性能运行 foo,但是 fooSingleThreadUserClass 会因为互斥开销而降低性能吗?我很想知道。或者我应该出于并发目的从 foo 派生 fooCC,以便 fooSingleThreadUserClas 可以继续使用没有互斥锁的 foo,而 fooMultiThreadUserClass 使用带有互斥锁的 fooCC,如下所示
\n\nclass fooCC : public foo{\n public:\n foo(){\n attr01 = 0;\n }\n void f(){ // I assume that foo::f() is now a virtual function.\n attr01Mutex.lock();\n foo::f();\n attr01Mutex.unlock();\n }\n private:\n std::mutex attr01Mutex;\n};\nRun Code Online (Sandbox Code Playgroud)\n\n还假设编译器优化已经处理了虚拟调度。我想知道是否应该使用继承或简单地将互斥锁放在原始类中。
\n\n我已经在 Stackoverflow 上进行了搜索,但我想我的问题有点太具体了。
\n\n编辑:注意,\xe2\x80\x99t 不必只有一个参数,这个问题应该是抽象的,具有一类 n 参数。
\n小智 5
使用std::lock_guard. 在其构造函数中lock_guard采用 a 。mutex在施工过程中,lock_guard锁定mutex。当lock_guard超出范围时,其析构函数会自动释放锁。
class foo
{
private:
std::mutex mutex;
int attr01;
public:
foo() {
attr01 = 0;
}
void f(){
std::lock_guard<std::mutex> lock (mutex);
attr01 += 5;
}
};
Run Code Online (Sandbox Code Playgroud)
如果您需要能够锁定或解锁from功能,您可以添加mutable。我通常会保留直到我特别需要它为止。mutexmutexconstmutablemutex
会损失性能吗?这取决于。如果您调用该函数一百万次,那么创建该函数的开销可能mutex会成为一个问题(它们并不便宜)。如果函数执行时间较长,并且被多个线程频繁调用,那么快速阻塞可能会影响性能。如果您无法查明具体问题,只需使用std::lock_guard.
汉斯·帕桑特提出了一个超出你问题范围的合理担忧。我认为赫伯·萨特(Herb Sutter)(?)在他的一篇网站文章中写到了这一点。不幸的是我现在找不到它。要理解为什么多线程如此困难,以及为什么单个数据字段上的锁“不够”,请阅读有关多线程编程的书,例如《C++ Concurrency in Action: Practical Multithreading》