问题
#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类资源