博客
关于我
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 幻读(Phantom Problem)不可重复读
查看>>
mysql 往字段后面加字符串
查看>>
mysql 快照读 幻读_innodb当前读 与 快照读 and rr级别是否真正避免了幻读
查看>>
MySQL 快速创建千万级测试数据
查看>>
mysql 快速自增假数据, 新增假数据,mysql自增假数据
查看>>
MySql 手动执行主从备份
查看>>
Mysql 批量修改四种方式效率对比(一)
查看>>
Mysql 报错 Field 'id' doesn't have a default value
查看>>
MySQL 报错:Duplicate entry 'xxx' for key 'UNIQ_XXXX'
查看>>
Mysql 拼接多个字段作为查询条件查询方法
查看>>
mysql 排序id_mysql如何按特定id排序
查看>>
Mysql 提示:Communication link failure
查看>>
mysql 插入是否成功_PDO mysql:如何知道插入是否成功
查看>>
Mysql 数据库InnoDB存储引擎中主要组件的刷新清理条件:脏页、RedoLog重做日志、Insert Buffer或ChangeBuffer、Undo Log
查看>>
mysql 数据库中 count(*),count(1),count(列名)区别和效率问题
查看>>
mysql 数据库备份及ibdata1的瘦身
查看>>
MySQL 数据库备份种类以及常用备份工具汇总
查看>>
mysql 数据库存储引擎怎么选择?快来看看性能测试吧
查看>>
MySQL 数据库操作指南:学习如何使用 Python 进行增删改查操作
查看>>