C++多线程-互斥锁(mutex)

         在多任务操作系统中,同时运行的多个任务可能都需要使用同一种资源。比如说,同一个文件,可能一个线程会对其进行写操作,而另一个线程需要对这个文件进行读操作,可想而知,如果写线程还没有写结束,而此时读线程开始了,或者读线程还没有读结束而写线程开始了,那么最终的结果显然会是混乱的。为了保护共享资源,在线程里也有这么一把锁——互斥锁(mutex),互斥锁是一种简单的加锁的方法来控制对共享资源的访问,互斥锁只有两种状态,即上锁( lock )和解锁( unlock )。

 互斥锁的特点

1. 原子性:把一个互斥量锁定为一个原子操作,这意味着如果一个线程锁定了一个互斥量,没有其他线程在同一时间可以成功锁定这个互斥量;

2. 唯一性:如果一个线程锁定了一个互斥量,在它解除锁定之前,没有其他线程可以锁定这个互斥量;

3. 非繁忙等待:如果一个线程已经锁定了一个互斥量,第二个线程又试图去锁定这个互斥量,则第二个线程将被挂起(不占用任何cpu资源),直到第一个线程解除对这个互斥量的锁定为止,第二个线程则被唤醒并继续执行,同时锁定这个互斥量。

互斥锁的使用

       根据前面我们可以知道,互斥锁主要就是用来保护共享资源的,在C++ 11中,互斥锁封装在mutex类中,通过调用类成员函数lock()和unlock()来实现加锁和解锁。值得注意的是,加锁和解锁,必须成对使用,这也是比较好理解的。除此之外,互斥量的使用时机,就以开篇程序为例,我们要保护的共享资源当然就是消息队列list了,那么互斥锁应该加在哪里呢?

#include<iostream>
#include<list>
#include"pthread.h"
#include"thread"
#include<mutex>

using namespace std;

class msgList
{
private:
	list<int>mylist;   //用list模仿一个消息队列
	mutex mtx;
public:
	void WriteList()   //向消息队列中写入消息(以i作为消息)
	{
		for (int i = 0; i < 1000; i++)
		{
			mtx.lock();
			cout << "Write : " << i << endl;
			mylist.push_back(i);
			mtx.unlock();
		}
		return;
	}
	void ReadList()  //从消息队列中读取并取出消息
	{
		for (int i = 0; i < 1000; i++)
		{
			if (!mylist.empty())
			{
				mtx.lock();
				cout << "Read : " << mylist.front() << endl;
				mylist.pop_front();
				mtx.unlock();
			}
			else
			{
				mtx.lock();
				cout << "Message List is empty!" << endl;
				mtx.unlock();
			}
		}
	}
};

        

上一篇:Hibernate逍遥游记-第13章 映射实体关联关系-005双向多对多(使用组件类集合\\)


下一篇:redis缓存穿透、缓存击穿、缓存雪崩区别和解决方案