c++11 线程支持库----通用互斥管理

std::lock_guard

template< class Mutex >
class lock_guard;

  
   

类 lock_guard 是互斥封装器,为在作用域块期间占有互斥提供便利 RAII 风格机制。

创建 lock_guard 对象时,它试图接收给定互斥的所有权。控制离开创建 lock_guard 对象的作用域时,销毁 lock_guard 并释放互斥。

lock_guard 类不可复制。

#include <thread>
#include <mutex>
#include <iostream>

int g_i = 0;
std::mutex g_i_mutex;  // 保护 g_i

void safe_increment()
{
	std::lock_guard<std::mutex> lock(g_i_mutex);
	++g_i;

	std::cout << std::this_thread::get_id() << ": " << g_i << '\n';

	// g_i_mutex 在锁离开作用域时自动释放
}

int main()
{
	std::cout << "main: " << g_i << '\n';

	std::thread t1(safe_increment);
	std::thread t2(safe_increment);

	t1.join();
	t2.join();

	std::cout << "main: " << g_i << '\n';
}

//可能输出:
main:0
11452:1
12504:2
main:2

std::unique_lock

类 unique_lock 是通用互斥包装器,允许延迟锁定、锁定的有时限尝试、递归锁定、所有权转移和与条件变量一同使用。

类 unique_lock 可移动,但不可复制——它满足可移动构造 (MoveConstructible) 和可移动赋值 (MoveAssignable) 但不满足可复制构造 (CopyConstructible) 或可复制赋值 (CopyAssignable) 。

类 unique_lock 满足基础可锁 (BasicLockable) 要求。若 Mutex 满足可锁 (Lockable) 要求,则 unique_lock 亦满足可锁(Lockable) 要求(例如:能用于 std::lock ) ;若 Mutex 满足定时可锁 (TimedLockable) 要求,则 unique_lock 亦满足定时可锁 (TimedLockable) 要求。

std::unique_lock::lock

//锁定关联互斥 。 等效地调用mutex()->lock()

#include <mutex>
#include <thread>
#include <iostream>
#include <vector>
#include <chrono>
 

/*下列示例用 lock 重获得被解锁的互斥。*/
int main()
{
    int counter = 0;
    std::mutex counter_mutex;
    std::vector<std::thread> threads;
 
    auto worker_task = [&](int id) {
        std::unique_lock<std::mutex> lock(counter_mutex);
        ++counter;
        std::cout << id << ", initial counter: " << counter << '\n';
        lock.unlock();
 
        // 我们模拟昂贵操作时不保有锁
        std::this_thread::sleep_for(std::chrono::seconds(1));
 
        lock.lock();
        ++counter;
        std::cout << id << ", final counter: " << counter << '\n';
    };
 
    for (int i = 0; i < 10; ++i) threads.emplace_back(worker_task, i);
 
    for (auto &thread : threads) thread.join();
}

//可能输出:

0, initial counter: 1
1, initial counter: 2
2, initial counter: 3
3, initial counter: 4
4, initial counter: 5
5, initial counter: 6
6, initial counter: 7
7, initial counter: 8
8, initial counter: 9
9, initial counter: 10
6, final counter: 11
3, final counter: 12
4, final counter: 13
2, final counter: 14
5, final counter: 15
0, final counter: 16
1, final counter: 17
7, final counter: 18
9, final counter: 19
8, final counter: 20

std::unique_lock::try_lock

bool try_lock();

尝试锁定关联互斥而不阻塞。等效地调用 mutex()->try_lock() 。

若无关联互斥或关联互斥已被此 std::unique_lock 锁定则抛出 std::system_error 。

std::unique_lock::try_lock_for

template< class Rep, class Period >
bool try_lock_for( const std::chrono::duration<Rep,Period>& timeout_duration );

尝试锁定关联互斥。阻塞直至经过指定的 timeout_duration 或获得锁,之先到来者。成功获得锁时返回 true ,否则返回 false 。等效地调用 mutex()->try_lock_for(timeout_duration) 。

由于调度或资源争议延迟,此函数可能阻塞长于 timeout_duration 。

标准建议用稳定时钟度量时长。若实现用系统时钟代替,则等待时间亦可能对时钟调节敏感。

若无关联互斥或若此 std::unique_lock 已锁定互斥则抛出 std::system_error 。

std::unique_lock::try_lock_until

template< class Clock, class Duration >
bool try_lock_until( const std::chrono::time_point<Clock,Duration>& timeout_time );

尝试锁定关联互斥。阻塞直至抵达指定的 timeout_time 或获得锁,之先到来者。成功获得锁时返回 true ,否则返回 false 。可能阻塞长于直至抵达 timeout_time 。

等效地调用 mutex()->try_lock_until(timeout_time) 。

若无关联互斥或已锁定互斥则抛出 std::system_error 。

std::unique_lock::unlock

void unlock();

解锁关联互斥并释放所有权。

若无关联互斥或互斥未被锁则抛出 std::system_error 。

std::defer_lock_t, std::try_to_lock_t, std::adopt_lock_t

struct defer_lock_t { };

struct try_to_lock_t { };

struct adopt_lock_t { };

std::defer_lock, std::try_to_lock, std::adopt_lock

std::defer_lockstd::try_to_lock 和 std::adopt_lock 分别是空结构体标签类型 std::defer_lock_t 、 std::try_to_lock_t 和 std::adopt_lock_t 的实例。

#include <mutex>
#include <thread>
#include<iostream>
struct bank_account {
	explicit bank_account(int balance) : balance(balance) {}
	int balance;
	std::mutex m;
};

void Transfer(bank_account &from, bank_account &to, int amount)
{
	// 锁定两个互斥而不死锁
	std::lock(from.m, to.m);
	// 保证二个已锁定互斥在作用域结尾解锁
	std::lock_guard<std::mutex> lock1(from.m, std::adopt_lock);
	std::lock_guard<std::mutex> lock2(to.m, std::adopt_lock);

	// 等价方法:
	//std::unique_lock<std::mutex> lock1(from.m, std::defer_lock);
	//std::unique_lock<std::mutex> lock2(to.m, std::defer_lock);
	//std::lock(lock1, lock2);

	std::cout << from.balance << ":" << to.balance << std::endl;
	from.balance -= amount;
	to.balance += amount;

	std::cout << "Transfer " << amount << "		from: " << from.balance
		<< "	to: " << to.balance << std::endl;
}

int main()
{
	bank_account my_account(100);
	bank_account your_account(50);

	std::thread t1(Transfer, std::ref(my_account), std::ref(your_account), 20);
	std::thread t2(Transfer, std::ref(your_account), std::ref(my_account), 5);

	t1.join();
	t2.join();
}


100:50
Transfer 20             from : 80        to : 70
70 : 80
Transfer 5              from : 65        to : 85


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值