写点什么

一个 cpp 协程库的前世今生(十七)带时限的锁

作者:SkyFire
  • 2022 年 1 月 11 日
  • 本文字数:1786 字

    阅读完需:约 6 分钟

一个cpp协程库的前世今生(十七)带时限的锁

为了防止大家找不到代码,还是先贴一下项目链接:


GitHub - skyfireitdiy/cocpp at cocpp-0.1.0


前面一共介绍了三种互斥量(锁),普通互斥量 co_mutex、递归互斥量 co_recursive_mutex、共享互斥量(读写锁)co_recursive_mutex。


每种互斥量都对应了一种带超时限制的版本:co_timed_mutex,co_recursive_timed_mutex,co_shared_timed_mutex。


前两种很简单,都是模板 co_timed_addition 的一个特化版本,如下(分别定义于 include/cocpp/sync/co_timed_mutex.h 和 include/cocpp/sync/co_recursive_timed_mutex.h):


using co_timed_mutex = co_timed_addition<co_mutex>; // 时间互斥锁using co_recursive_timed_mutex = co_timed_addition<co_recursive_mutex>; // 递归时间互斥锁
复制代码


co_shared_timed_mutex 要多几个接口,因此它是继承自 co_timed_addition<co_shared_mutex>


所以接下来我们重点分析一下 co_timed_addition 这个模板类。

co_timed_addition

这个模板类定义在 include/cocpp/sync/co_timed_addition.h:


template <class Lock>class co_timed_addition : public Lock{public:    template <class Rep, class Period>    bool try_lock_for(const std::chrono::duration<Rep, Period>& timeout_duration); // 尝试加锁    template <class Clock, class Duration>    bool try_lock_until(const std::chrono::time_point<Clock, Duration>& timeout_time); // 尝试加锁};
// 模板实现
template <class Lock>template <class Rep, class Period>bool co_timed_addition<Lock>::try_lock_for(const std::chrono::duration<Rep, Period>& timeout_duration){ return try_lock_until(std::chrono::high_resolution_clock::now() + timeout_duration);}
template <class Lock>template <class Clock, class Duration>bool co_timed_addition<Lock>::try_lock_until(const std::chrono::time_point<Clock, Duration>& timeout_time){ do { if (Lock::try_lock()) { return true; } co::current_env()->schedule_switch(); } while (std::chrono::high_resolution_clock::now() < timeout_time); return false;}
复制代码


这就是这个模板类的整个定义与实现了,为模板参数增加 try_lock_for 和 try_lock_until 两个函数,其实现依赖于 try_lock 接口。在指定时间到达之前会不断地尝试。直到到达指定的时间或者获取锁成功为止。


上面提到,co_shared_timed_mutex 继承自 co_timed_addition<co_shared_mutex>

co_shared_timed_mutex

其接口与实现如下(include/cocpp/sync/co_shared_timed_mutex.h):


class co_shared_timed_mutex : public co_timed_addition<co_shared_mutex>{public:    template <class Rep, class Period>    bool try_lock_shared_for(const std::chrono::duration<Rep, Period>& timeout_duration); // 尝试加共享锁    template <class Clock, class Duration>    bool try_lock_shared_until(const std::chrono::time_point<Clock, Duration>& timeout_time); // 尝试加共享锁};
// 模板实现
template <class Rep, class Period>bool co_shared_timed_mutex::try_lock_shared_for(const std::chrono::duration<Rep, Period>& timeout_duration){ return try_lock_shared_until(std::chrono::high_resolution_clock::now() + timeout_duration);}
template <class Clock, class Duration>bool co_shared_timed_mutex::try_lock_shared_until(const std::chrono::time_point<Clock, Duration>& timeout_time){ do { if (try_lock_shared()) { return true; } co::current_env()->schedule_switch(); } while (std::chrono::high_resolution_clock::now() < timeout_time); return false;}
复制代码


在 co_timed_addition<co_shared_mutex>的基础上又增加了两个成员函数 try_lock_shared_for 和 try_lock_shared_until,其实现与 co_timed_addition 中的 try_lock_for、try_lock_until 异曲同工,这里就不做深入分析了。

总结

本文介绍了前面三种互斥量对应的带时限的版本,总体来说就是利用一个模板类为现有的实现增加接口,衍生出功能更丰富的类,这个编程技巧在很多功能封装场景下都挺有用的。

发布于: 刚刚阅读数: 2
用户头像

SkyFire

关注

这个cpper很懒,什么都没留下 2018.10.13 加入

会一点点cpp的苦逼码农

评论

发布
暂无评论
一个cpp协程库的前世今生(十七)带时限的锁