#include <iostream>
#include <thread>
#include <chrono>
#include <mutex>
#include <condition_variable>
#include <string>
#include <list>
/*****************************************************************************
多线程 & 互斥锁 & 条件变量
多线程
1. 创建线程后,一定要记得释放线程
2. 多线程中能不共享的资源,就不共享
3. 共享的资源注意,各线程访问时的安全问题
4. 线程内需要访问被创建时的范围内对象(外部)时,尽量用lambda进行传参
5. 使用thread创建线程传参时,函数体的参数如果是引用,需要加std::ref
互斥锁
1. 锁的范围因该尽可能地小
2. 不建议直接用mutex对象的lock和unlock成员函数进行线程间的锁操作(易死锁)
3. 建议使用范围性的锁lock_guard类模板定义对象管理mutex锁
4. 多个锁在同一范围内使用时,建议使用std的lock函数模板管理多个mutex
条件变量
1. 任务需要等待某个条件才可以执行,避免循环判断条件导致CPU使用飙升
2. 条件变量 condition_variable 需要结合 mutex 和 unique_lock 一起使用
*****************************************************************************/
std::mutex m,n;
void referencefunc(int &num)
{
num = 100;
}
void bodyfunc(int times)
{
for (int i = 0; i < times; ++i)
{
{//加锁保证下面的打印在一行,不会被其他插入
std::lock_guard<std::mutex> nguard(n);
std::cout << i << " " << std::this_thread::get_id() << std::endl;;
}
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
}
void doublelockfunc(int& a, int& b)
{
//同时控制两个不同的锁,而且需要他们控制的内容同步时
//建议std::lock和std::lock_guard结合使用。
//进入范围后m、n既被lock锁住,又可以在离开范围时自动解锁
//而且不会存在: 不同线程也使用这两把锁时,
// 由于加锁顺序不同而可能出现的死锁情况
std::lock(m, n);
std::lock_guard<std::mutex> mguard(m, std::adopt_lock);
std::lock_guard<std::mutex> nguard(n, std::adopt_lock);
a++;
b++;
}
std::mutex mtx;
std::condition_variable cv;
std::list<std::string> messageList;
bool conditionfunc()
{
//需要满足的条件,当返回真时才会执行 wait 后面的代码
return messageList.size() > 0;
}
void conditionvariableThread()
{
std::cout << "ConditionvariableThread is started !" << std::endl;
std::unique_lock<std::mutex> ulock(mtx);
cv.wait(ulock, conditionfunc);
std::cout << messageList.front() << std::endl;
}
void testThread()
{
int v = 0;
//使用thread调用lambda形式
std::thread th1([&v]() {
referencefunc(v);
});
th1.join();
std::cout << "after lambda v = " << v << std::endl;
v = 0;
//使用thread调用函数形式
std::thread th2(referencefunc, std::ref(v));
th2.join();
std::cout << "after thread v = " << v << std::endl;
//线程内多把锁同时控制时
int v1 = 0, v2 = 0;
std::thread th3([&v1, &v2]() { doublelockfunc(v1, v2); });
th3.join();
//条件变量
std::thread th4(conditionvariableThread);
std::this_thread::sleep_for(std::chrono::milliseconds(10));
std::cout << "10 milliseconds later !" << std::endl;
{
std::unique_lock<std::mutex> glock(mtx);
messageList.emplace_back("Now is my turn !");
}
cv.notify_one();
th4.join();
//多线程任务
std::thread th(bodyfunc, 10);
bodyfunc(10);
th.join();
}
C++11学习笔记 -- thread&mutex
于 2022-01-25 11:22:27 首次发布