#include <future> #include <mutex> #include <iostream> #include <string> #include <exception> #include <stdio.h> using namespace std; mutex printMutex; static string s = "Hello from a first thread"; void print() { try{ cout << "thread start:" << this_thread::get_id() << endl; lock_guard<mutex> l(printMutex);//它只能保证你的thread不能并发(在printMutex没有释放前,它可以阻塞其他的调用),但是后面的s数据可以被改变 /*这样的lock应该被限制在可能之最短周期内,因为它们会阻塞(block)其他代码的并行运行机会。由于析构 函数会释放这个lock,你或许会想明确安插大括号,令lock在更近一步语句被处理前先被释放*/ for (char c : s) { this_thread::sleep_for(chrono::milliseconds(500)); cout.put(c); } cout << endl; } catch (const exception& e) { cerr << "EXCEPTION: " << e.what() << endl; } } int main() { try{ auto f1 = async(launch::async, print); s = "Hello from a second thread"; auto f2 = async(launch::async, print); this_thread::sleep_for(chrono::milliseconds(20000)); s = "Hello from the main thread"; print(); } catch (const exception& e) { cerr << "EXCEPTION: " << e.what() << " On Main " << endl; } system("pause"); return 0; }
有时候我们会遇到这种情况:
当我们定义一个类,我们定义了private 的mutex 变量。并且在类里的函数中进行了锁定(lock_guard<mutex>lg(变量))。当我们在某个函数中进行锁定mutex 变量,并且我们在其后面调用了我们有锁定变量的类函数。
这样会造成死锁的情况出现。因为我们已经锁住了mutex 变量,但是后面的语句中我们还要锁定mutex 变量,所以第二次锁定的mutex 变量要等待第一次mutex 变量解锁,但是该函数没有运行完第一次锁定的mutex 变量不会被析构函数将这个lock释放掉,所以线程一直在等待,造成死锁。
解决方案:我们可以使用recursive_mutex 来进行定义mutex变量。
recursive_mutex允许同一线程多次锁定,并在最近的一次(last)相应的unlock时释放lock。