C++多线程3

weakcore / 2024-01-21 / 原文

1 利用栈特性自动释放锁RAII

1.1 什么是RAII

RAII(Resource Acquisition Is Initialization),使用局部对象管理资源的技术称为资源获取既初始化,它的生命周期由操作系统管理,无需人工干预。为什么要引入自动释放锁,因为我们有时会因为忘记释放锁,而造成死锁或内存泄漏。我们先来手动实现,来理解一下它的处理过程
代码如下:

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

class xmux {
public:
	xmux(mutex& mux):mux_ (mux){
		
		
		mux_.lock();
		cout << "lock" << endl;
	}
	~xmux() {
		cout << "unlock" << endl;
		mux_.unlock();
	}
private:
	mutex& mux_;
};
static mutex mux;
void test(int i) {
	xmux mu(ref(mux));
	if (i == 1) {
		cout << i << endl;
		return;
	}
	else {
		cout << "2" << endl;
		return;
	}
}
int main() {
	for (int i = 0; i < 3; i++) {
		thread th(test, i);
		th.detach();
	}
	getchar();
}

运行结果:

1.2 C++11所支持的RAII管理互斥资源lock_guard;

我们先来看一下lock_guard的源码:

_EXPORT_STD template <class _Mutex>
class _NODISCARD_LOCK lock_guard { // class with destructor that unlocks a mutex
public:
    using mutex_type = _Mutex;

    explicit lock_guard(_Mutex& _Mtx) : _MyMutex(_Mtx) { // construct and lock
        _MyMutex.lock();
    }

    lock_guard(_Mutex& _Mtx, adopt_lock_t) : _MyMutex(_Mtx) {} // construct but don't lock

    ~lock_guard() noexcept {
        _MyMutex.unlock();
    }

    lock_guard(const lock_guard&)            = delete;
    lock_guard& operator=(const lock_guard&) = delete;

private:
    _Mutex& _MyMutex;
};

我们可以看到它是一个模板函数,意味这lock_guard这个类可以实现其他的锁,比如超时锁,共享锁等。此外它提供了两个构造函数一个实现了正常加锁,另一个不做任何操作,用以处理已经加过锁的mutex。lock_guard(const lock_guard&) = delete;和lock_guard& operator=(const lock_guard&) = delete;表示不允许锁的转移。下面是示例: