博客
关于我
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-数据目录
查看>>
MySQL-数据页的结构
查看>>
MySQL-架构篇
查看>>
MySQL-索引的分类(聚簇索引、二级索引、联合索引)
查看>>
Mysql-触发器及创建触发器失败原因
查看>>
MySQL-连接
查看>>
mysql-递归查询(二)
查看>>
MySQL5.1安装
查看>>
mysql5.5和5.6版本间的坑
查看>>
mysql5.5最简安装教程
查看>>
mysql5.6 TIME,DATETIME,TIMESTAMP
查看>>
mysql5.6.21重置数据库的root密码
查看>>
Mysql5.6主从复制-基于binlog
查看>>
MySQL5.6忘记root密码(win平台)
查看>>
MySQL5.6的Linux安装shell脚本之二进制安装(一)
查看>>
MySQL5.6的zip包安装教程
查看>>
mysql5.7 for windows_MySQL 5.7 for Windows 解压缩版配置安装
查看>>