目录

c介绍锁二

目录

c++介绍锁二

锁主要在两个以上的线程中使用,当多个线程访问共享资源时,我们需要使用锁,开保证共享资源的唯一性。

当两个线程访问不带锁的共享资源时,如下代码

#include<array>
#include<thread>
#include<iostream>
using namespace std;

void inc(int& res)
{
	for (int i = 0; i < 1000000; i++)
		res++;
}
int main1()
{
	int counter = 0;
	thread th1(inc,ref(counter));
	thread th2(inc, ref(counter));
	th1.join();
	th2.join();
	cout << "counter =" << counter << "\n";
	return 0;
}

得到结果 https://i-blog.csdnimg.cn/direct/1e6034a1cf7f4978a1a5655ef403dd80.png

显然结果是不正确的。

这时我们需要加锁来限制

#include<array>
#include<thread>
#include<iostream>
#include<mutex>
using namespace std;


class Counter {
public:
	void inc()
	{
		counter_mutex.lock();
		m_count++;
		counter_mutex.unlock();
	}
	int getCounter()    //如果在多线程调用也需要加锁  这里没在多线程调用也加了锁
	{
		int temp;
		counter_mutex.lock();
		temp = m_count;
		counter_mutex.unlock();
		return temp;
	}
private:
	mutex counter_mutex;
	int m_count = 0;
};
int main2()
{
	Counter counter;
	auto increase = [](Counter& counter)
	{
		for (int i = 0; i < 1000000; i++)
			counter.inc();
	};
	thread th1(increase, ref(counter));
	thread th2(increase,ref(counter));
	th1.join();
	th2.join();
cout << "counter=" << counter.getCounter()<<"\n";
return 0;
}

由于上述加锁,代码的健壮性不是很好,如果遇到异常抛出情况,可能存在互斥量未释放问题。所以进一步改进

如下代码

#include<array>
#include<thread>
#include<iostream>
#include<mutex>
using namespace std;


class Counter {
public:
	void inc()
	{
		lock_guard<mutex> lock(counter_mutex);
		m_count++;
	}
	int getCounter()
	{
		int temp;
		lock_guard<mutex> lock(counter_mutex);
		temp = m_count;
		return temp;
	}
private:
	mutex counter_mutex;
	int m_count = 0;
};
int main2()
{
	Counter counter;
	auto increase = [](Counter& counter)
	{
		for (int i = 0; i < 1000000; i++)
			counter.inc();
	};
	thread th1(increase, ref(counter));
	thread th2(increase,ref(counter));
	th1.join();
	th2.join();
cout << "counter=" << counter.getCounter()<<"\n";
return 0;
}

这样只要不在作用域范围内,锁就会释放,可以避免上述问题。

unique_lock更加灵活,可以创建后不锁定,在使用过程中进行锁定。

#include<array>
#include<thread>
#include<iostream>
#include<mutex>
using namespace std;

class Counter
{
public:

	void increase(int n)
	{
		unique_lock<mutex>lock(counter_mutex,defer_lock);//延迟获取锁
		while (n--)
		{
			lock.lock();
			m_count++;
			lock.unlock();
		}
	}
	int getCount()
	{
		unique_lock<mutex> lock(counter_mutex);
		return m_count;
	}
private:
	mutex counter_mutex;
	int m_count = 0;
};
void main3()
{
	Counter counter;
	auto increase = [](Counter& counter) {
		counter.increase(1000000);
	};
	thread th1(increase, ref(counter));
	thread th2(increase, ref(counter));

	th1.join();
	th2.join();
	cout << "counter=" << counter.getCount() << "\n";

}

还有一种计时锁,设定在多少时间内进行锁定

#include<array>
#include<thread>
#include<iostream>
#include<mutex>
using namespace std;
//time_mutex

using namespace std::chrono_literals;
class TryDemo
{
public:
	void print()
	{
		for (int i =0; i < 10; i++)
		{
			unique_lock<timed_mutex>lock(m_mutex,defer_lock);

			if (lock.try_lock_for(100ms))//100ms是否获得该锁
			{
				{
					lock_guard<mutex> guard(count_mutex);
					cout << "[" << this_thread::get_id << "]" << "成功;\n";
				}
				this_thread::sleep_for(100ms);
			}
			else
			{
				lock_guard<mutex> lock_guard(count_mutex);
				cout << "[" << this_thread::get_id() << "]" << "失败;\n";
				this_thread::sleep_for(100ms);
			}
		}
	}
private:
	timed_mutex m_mutex;
	mutex count_mutex;
	int m_count = 0;
};
void main5()
{
	TryDemo demo;
	auto print = [](TryDemo& demo)
	{
		demo.print();
	};
		thread th1(print,ref(demo));
		thread th2(print, ref(demo));
		th1.join();
		th2.join();
}