C++11学习笔记 -- thread&mutex

#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();
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值