问题
#include <iostream>#include <string>#include <thread>using namespace std;void function_1() { for (int i = 0; i > -100; i--) cout << "From t1:" << i << endl;}int main() { thread t1(function_1); for (int i = 0; i > -100; i--) cout << "From main:" << i << endl; t1.join(); return 0;}
- main线程和function_1线程争抢cout资源,导致输出错乱
- 本来cout在打印main的内容,被打断,打印function_1内容
加互斥锁
#include <iostream>#include <string>#include <thread>#include <mutex>std::mutex mu;void share_print(std::string msg,int id) { mu.lock(); std::cout << msg << id << std::endl; mu.unlock();}void function_1() { for (int i = 0; i > -100; i--) share_print("From t1:", i);}int main() { std::thread t1(function_1); for (int i = 0; i > -100; i--) share_print("From main:", i); t1.join(); return 0;}
- 互斥量类
mutex - lock方法,当有一个线程执行到cout前,对这一段上锁
- 另一个线程想要执行cout,如果有锁,无法执行,被挂起
- 执行完cout才可解锁,让下一个线程执行
- 存在问题
- 如果lock和unlock之间出现异常,会导致始终锁着,线程始终无法进行
防异常互斥
#include <iostream>#include <string>#include <thread>#include <mutex>std::mutex mu;void share_print(std::string msg,int id) { std::lock_guard<std::mutex> guard(mu); std::cout << msg << id << std::endl;}void function_1() { for (int i = 0; i > -100; i--) share_print("From t1:", i);}int main() { std::thread t1(function_1); for (int i = 0; i > -100; i--) share_print("From main:", i); t1.join(); return 0;}
- 使用lock_guard可以自动完成上锁和开锁,如果保护内容发生异常,会自动开锁
- 存在问题
- cout是全局变量,除了这两个线程会用,其它地方也会抢占
- cout没有完全在互斥对象mu的保护下
- 互斥资源必须和互斥对象进行绑定
互斥锁私有资源
#include <iostream>#include <string>#include <thread>#include <mutex>#include <fstream>class LofFile{public: LofFile(); ~LofFile(); void share_print(std::string id, int value);private: std::mutex m_mutex; std::ofstream f;//f是被mutex所保护的资源};LofFile::LofFile(){ f.open("log.txt");}LofFile::~LofFile(){}void LofFile::share_print(std::string id, int value){ std::lock_guard<std::mutex> locker(m_mutex); f << "from" << id << ":" << value << std::endl;}void function_1(LofFile& log) { for (int i = 0; i > -100; i--) log.share_print("From function_1:", i);}int main() { LofFile log; std::thread t1(function_1,std::ref(log)); for (int i = 0; i > -100; i--) log.share_print("From main:", i); t1.join(); return 0;}
- 用文件操作代替cout
- 文件操作和互斥锁绑定
- 两个线程将抢夺的是LofFile类资源