博客
关于我
C++基于RAII对锁进行封装
阅读量:730 次
发布时间:2019-03-21

本文共 3697 字,大约阅读时间需要 12 分钟。

\n\n\n\n\n
\n

\n
\n

RAII简介

\n
\n

RAII(Resource Acquisition Is Initialization,是C++语言的一种资源管理方法,旨在避免资源泄漏。C++的对象特性保证了任何构造的对象最终都会被销毁,析构函数最终将被调用。RAII的核心思想是使用对象在构造时获取资源,在对象的生命周期内控制资源的访问权限,并在对象的析构时释放资源。这种方式确保了资源的所有权和控制权,使得开发者无需手动管理资源的生命周期。

\n
\n

RAII分类

\n
\p>根据资源的所有权,RAII可分为常性类型和变性类型。常性类型的资源获取和释放点固定,资源在构造函数获取,在析构函数释放,且在这两点之间资源的所有权由该RAII实例持有。变性类型的资源可以在中途被移交给另一个RAII实例,或者完全释放资源所有权。从资源获取的位置看,RAII又可分为外部初始化类型和内部初始化类型。外部初始化类型的资源是在外部创建后由RAII实例接管,而内部初始化类型的资源则由RAII实例自身创建并管理。

\n
\n

基于RAII对锁进行封装

\n
\n

以下是基于RAII对各种锁进行封装的实现代码示例:

\n
\n#ifndef __LOCK_H\n#define __LOCK_H\n#include
\n#include
\n#include
\n#include
\n#include
\n\nstruct Noncopyable {\n Noncopyable() = default;\n ~Noncopyable() = default;\n Noncopyable(const Noncopyable&) = delete;\n Noncopyable& operator=(const Noncopyable&) = delete;\n};\n\nclass Semaphore : Noncopyable {\npublic:\n explicit Semaphore(uint32_t count = 0) {\n sem_init(&m_sem, 0, count);\n }\n ~Semaphore() {\n sem_destroy(&m_sem);\n }\n void wait() {\n sem_wait(&m_sem);\n }\n void notify() {\n sem_post(&m_sem);\n }\nprivate:\n sem_t m_sem;\n};\n\ntemplate
\nclass ScopedLock {\npublic:\n ScopedLock(T& m) : m_mutex(m) {\n lock();\n }\n ~ScopedLock() {\n unlock();\n }\n void lock() {\n if (!m_lock) {\n m_mutex.lock();\n m_lock = true;\n }\n }\n void unlock() {\n if (m_lock) {\n m_mutex.unlock();\n m_lock = false;\n }\n }\nprivate:\n T& m_mutex;\n bool m_lock = false;\n};\n\ntemplate
\nclass WriteScopedLock {\npublic:\n WriteScopedLock(T& m) : m_mutex(m) {\n lock();\n }\n ~WriteScopedLock() {\n unlock();\n }\n void lock() {\n if (!m_lock) {\n m_mutex.wrlock();\n m_lock = true;\n }\n }\n void unlock() {\n if (m_lock) {\n m_mutex.unlock();\n m_lock = false;\n }\n }\nprivate:\n T& m_mutex;\n bool m_lock = false;\n};\n\ntemplate
\nclass ReadScopedLock {\npublic:\n ReadScopedLock(T& m) : m_mutex(m) {\n lock();\n }\n ~ReadScopedLock() {\n unlock();\n }\n void lock() {\n if (!m_lock) {\n m_mutex.rdlock();\n m_lock = true;\n }\n }\n void unlock() {\n if (m_lock) {\n m_mutex.unlock();\n m_lock = false;\n }\n }\nprivate:\n T& m_mutex;\n bool m_lock = false;\n};\n\nclass Mutex : Noncopyable {\npublic:\n typedef ScopedLock
Lock;\n Mutex() {\n pthread_mutex_init(&m_mutex, nullptr);\n }\n ~Mutex() {\n pthread_mutex_destroy(&m_mutex);\n }\n void lock() {\n pthread_mutex_lock(&m_mutex);\n }\n int trylock() {\n pthread_mutex_trylock(&m_mutex);\n }\n void unlock() {\n pthread_mutex_unlock(&m_mutex);\n }\nprivate:\n pthread_mutex_t m_mutex;\n};\n\nclass RWMutex : Noncopyable {\npublic:\n typedef WriteScopedLock
WriteLock;\n typedef ReadScopedLock
ReadLock;\n RWMutex() {\n pthread_rwlock_init(&m_lock, nullptr);\n }\n ~RWMutex() {\n pthread_rwlock_destroy(&m_lock);\n }\n void rdlock() {\n pthread_rwlock_rdlock(&m_lock);\n }\n void wrlock() {\n pthread_rwlock_wrlock(&m_lock);\n }\n void unlock() {\n pthread_rwlock_unlock(&m_lock);\n }\nprivate:\n pthread_rwlock_t m_lock;\n};\n\nclass SpinLock : Noncopyable {\npublic:\n typedef ScopedLock
Lock;\n SpinLock() {\n pthread_spin_init(&m_mutex, 0);\n }\n ~SpinLock() {\n pthread_spin_destroy(&m_mutex);\n }\n void lock() {\n pthread_spin_lock(&m_mutex);\n }\n int trylock() {\n pthread_spin_trylock(&m_mutex);\n }\n void unlock() {\n pthread_spin_unlock(&m_mutex);\n }\nprivate:\n pthread_spinlock_t m_mutex;\n};\n\nclass CASLock : Noncopyable {\npublic:\n typedef ScopedLock
Lock;\n CASLock() {\n m_mutex.clear();\n }\n ~CASLock() {\n }\n void lock() {\n while (std::atomic_flag_test_and_set_explicit(&m_mutex, std::memory_order_acquire));\n }\n void unlock() {\n std::atomic_flag_clear_explicit(&m_mutex, std::memory_order_release);\n }\nprivate:\n volatile std::atomic_flag m_mutex;\n}\n\n#endif /**__LOCK_H*/
\n\n\n

转载地址:http://gtsgz.baihongyu.com/

你可能感兴趣的文章
mysql 协议的退出命令包及解析
查看>>
mysql 取表中分组之后最新一条数据 分组最新数据 分组取最新数据 分组数据 获取每个分类的最新数据
查看>>
mysql 多个表关联查询查询时间长的问题
查看>>
mySQL 多个表求多个count
查看>>
mysql 多字段删除重复数据,保留最小id数据
查看>>
MySQL 多表联合查询:UNION 和 JOIN 分析
查看>>
MySQL 大数据量快速插入方法和语句优化
查看>>
mysql 如何给SQL添加索引
查看>>
mysql 字段区分大小写
查看>>
mysql 字段合并问题(group_concat)
查看>>
mysql 字段类型类型
查看>>
MySQL 字符串截取函数,字段截取,字符串截取
查看>>
MySQL 存储引擎
查看>>
mysql 存储过程 注入_mysql 视图 事务 存储过程 SQL注入
查看>>
MySQL 存储过程参数:in、out、inout
查看>>
mysql 存储过程每隔一段时间执行一次
查看>>
mysql 存在update不存在insert
查看>>
Mysql 学习总结(86)—— Mysql 的 JSON 数据类型正确使用姿势
查看>>
Mysql 学习总结(87)—— Mysql 执行计划(Explain)再总结
查看>>
Mysql 学习总结(88)—— Mysql 官方为什么不推荐用雪花 id 和 uuid 做 MySQL 主键
查看>>