线程上锁

目录

1、线程上锁的原因

2、Mutex

3、Lock_guard<>

4、Unique_lock<> 同上,但多三个构造函数

5、区别

6、测试代码


1、线程上锁的原因

1)避免未同步的数据访问;

2)避免读写一般的数据被更改;

3)避免因线程函数体内“表达式重新排列引起”的逻辑问题。

2、Mutex

互斥锁:一般用来保护共享资源。

Mutex m;               构造,建立一个未锁定的对象
M.~Mutex();            销毁,但必须未锁定
M.lock();              上锁
M.try_lock();          上锁,成功返回true
M.try_lock_until(tp);  在时间点tp前锁住,成功返回true
M.try_lock_for(dur);   在时间段dur内锁住,成功返回true
M.unlock();            解锁
M.native_handle();     为了不具有可移植性的扩展

3、Lock_guard<>

在该对象的生命周期结束时,自动释放对象。解决未解锁就跳出函数,不在进行解锁行为造成的异常。

4、Unique_lock<> 同上,但多三个构造函数

unique_lock l;        创建一个不关联的mutex
unique_lock l(m);     为mutex建立一个lock_guard
unique_lock l(m,adopt_lock);    为已锁定的mutex建立一个lock_guard
unique_lock L(m,defer_lock);    为mutex建立一个lock_guard但不锁定它
unique_lock l(m,try_lock);      为mutex建立一个lock_guard并试图锁住他
unique_lock l(m,dur);           为mutex建立一个lock_guard并试图锁在时间段dur内锁住他
unique_lock k(m,tp);            为mutex建立一个lock_guard并试图锁在时间点tp前锁住他
unique_lock l(rv);              Move 构造
L.~Unique_lock ();              解锁并销毁
unique_lock l= rv;              Move assignment
swap(l1,l2);                    交换lock
L1.swap(l2);                    交换lock
L.release();                    返回一个pointer指向关联的mutex并释放之
L.owns_lock();                  如果关联的mutex被锁定,返回true
if(l);                          检查关联的mutex是否被锁定
L.mutex();                      返回pointer指向关联的mutex
L.lock();                       锁住关联的mutex
L.try_lock();                   尝试上锁,成功返回true
L.try_lock_for(dur);            尝试在时间段内上锁,成功返回true
L.try_lock_until(tp);           尝试在时间点tp前上锁,成功返回true
L.unlock();                     解除关联的mutex

5、区别

序号

操作

Mutex

Recursive_mutex

Timed_mutex

Recursive_timed_mutex

1

Lock()

捕获mutex(若无捕获阻塞)

2

Try_lock()

捕获mutex(若无捕获返回false)

3

Unlock()

解除mutex

4

Try_lock_for()

-

-

试图在时间段内捕获lock

5

Try_lock_until()

-

-

试着在时间点前捕获lock

6、测试代码

#include <iostream>
#include <thread>
#include <mutex>
#include <future>
#include <condition_variable> //使用条件变量必须包含该头文件和mutex
using namespace std;

mutex valMutex;

recursive_mutex reMutex;

void Mutex_Print(const string & s)
{
	valMutex.lock();
	//试图上锁。已经上锁返回0
	cout << "Mutex_Print " << valMutex.try_lock() << ends;
	for (char c : s)
	{
		cout.put(c);
	}
	cout << endl;
	valMutex.unlock();
}

void lock_guard_Print(const string & s)
{
	lock_guard<mutex> lg(valMutex);
	cout << "lock_guard_Print" << ends;
	for (char c : s)
	{
		cout.put(c);
	}
	cout << endl;
}

void unique_lock_Print(const string & s)
{
	valMutex.lock();
	//为已经锁定的mutex建立一个lock_guard
	unique_lock<mutex> lg(valMutex,adopt_lock);
	cout << "unique_lock_Print " << ends;
	for (char c : s)
	{
		cout.put(c);
	}
	cout << endl;
}

void testDeadlock_mutext()
{
	valMutex.lock();
	cout << "  Using mutex to test deadlock." << endl;
	valMutex.unlock();
}

void testDeadlock_recursive_mutex()
{
	reMutex.lock();
	cout << "  Using recursive_mutex to test deadlock." << endl;
	reMutex.unlock();
}

int main()
{
	//测试Mutex锁
	auto f1 = async(launch::async, Mutex_Print, "123465789");
	auto f2 = async(launch::async, Mutex_Print, "JQKA");

	//测试lock_guard<>  自动解锁功能
	auto f3 = async(launch::async, lock_guard_Print, "123465789");
	auto f4 = async(launch::async, lock_guard_Print, "JQKA");

	//测试unique_lock<>  自动解锁功能
	auto f5 = async(launch::async, unique_lock_Print, "123465789");
	auto f6 = async(launch::async, unique_lock_Print, "JQKA");

	//测试死锁
	{
#if 0

		//连续锁两次会崩
		lock_guard<mutex> lg(valMutex);
		testDeadlock_mutext();
#else
		//允许同一时间内,多次被同一个线程获取lock
		lock_guard<recursive_mutex> lg(reMutex);
		testDeadlock_recursive_mutex();
#endif
	}
	system("pause");
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值