Linux下线程pthread以及锁的一些总结和代码参考
2016-03-22 00:00
615 查看
摘要: 本博客主要讲解下本人对linux中线程以及锁的一些认识,以及自己用c++封装的一些锁的基本功能,欢迎大家指导。
对于linux下线程pthread的认识以及锁的相关概念等等,作为小白的我推荐这一篇比较好的文章,也谢谢大牛的分享:
http://casatwy.com/pthreadde-ge-chong-tong-bu-ji-zhi.html
对于只使用基本mutex的同学,摘录文章中的一段话,共同勉励,一起养成良好的编码规范:
如果要进入一段临界区需要多个mutex锁,那么就很容易导致死锁,单个mutex锁是不会引发死锁的。要解决这个问题也很简单,只要申请锁的时候 按照固定顺序,或者及时释放不需要的mutex锁就可以。这就对我们的代码有一定的要求,尤其是全局mutex锁的时候,更需要遵守一个约定。
如果是全局mutex锁,我习惯将它们写在同一个头文件里。一个模块的文件再多,都必须要有两个umbrella header file。一个是整个模块的伞,外界使用你的模块的时候,只要include这个头文件即可。另一个用于给模块的所有子模块去include,然后这个头 文件里面就放一些公用的宏啊,配置啊啥的,全局mutex放在这里就最合适了。这两个文件不能是同一个,否则容易出循环include的问题。如果有人写 模块不喜欢写这样的头文件的,那现在就要改了。
然后我的mutex锁的命名规则就是:
如果是属于某个struct内部的mutex锁,那么也一样,只不过序号可以不必跟全局锁挂钩,也可以从1开始数。
以下是本人平时代码中参考别人代码之后,用c++封装的关于锁以及线程同步条件变量的代码参考,欢迎指导:
对于linux下线程pthread的认识以及锁的相关概念等等,作为小白的我推荐这一篇比较好的文章,也谢谢大牛的分享:
http://casatwy.com/pthreadde-ge-chong-tong-bu-ji-zhi.html
对于只使用基本mutex的同学,摘录文章中的一段话,共同勉励,一起养成良好的编码规范:
如果要进入一段临界区需要多个mutex锁,那么就很容易导致死锁,单个mutex锁是不会引发死锁的。要解决这个问题也很简单,只要申请锁的时候 按照固定顺序,或者及时释放不需要的mutex锁就可以。这就对我们的代码有一定的要求,尤其是全局mutex锁的时候,更需要遵守一个约定。
如果是全局mutex锁,我习惯将它们写在同一个头文件里。一个模块的文件再多,都必须要有两个umbrella header file。一个是整个模块的伞,外界使用你的模块的时候,只要include这个头文件即可。另一个用于给模块的所有子模块去include,然后这个头 文件里面就放一些公用的宏啊,配置啊啥的,全局mutex放在这里就最合适了。这两个文件不能是同一个,否则容易出循环include的问题。如果有人写 模块不喜欢写这样的头文件的,那现在就要改了。
然后我的mutex锁的命名规则就是:
作用_mutex_序号,比
如
LinkListMutex_mutex_1,
OperationQueue_mutex_2,后面的序号在每次有新锁的时候,就都加一个1。如果有哪个临界区进入的时候需要获得多个mutex锁的,我就按照序号的顺序去进行加锁操作(pthread_mutex_lock),这样就能够保证不会出现死锁了。
如果是属于某个struct内部的mutex锁,那么也一样,只不过序号可以不必跟全局锁挂钩,也可以从1开始数。
以下是本人平时代码中参考别人代码之后,用c++封装的关于锁以及线程同步条件变量的代码参考,欢迎指导:
#ifndef _MUTEX_HELPER_HPP_ #define _MUTEX_HELPER_HPP_ #include <pthread.h> namespace clientAPI { //互斥锁 class MutexLock { public: MutexLock(){ pthread_mutex_init(&m_stMutex, NULL); } ~MutexLock(){ pthread_mutex_destroy(&m_stMutex); } void lock(){ pthread_mutex_lock(&m_stMutex); } int unlock() { return pthread_mutex_unlock(&m_stMutex); } bool trylock(){ return pthread_mutex_trylock(&m_stMutex) == 0;} pthread_mutex_t* getMutexPtr(){ return &m_stMutex;} private: pthread_mutex_t m_stMutex; }; //读写锁 class ReadWriteLock { public: ReadWriteLock() { pthread_rwlock_init(&m_stReadWrite, NULL); } ~ReadWriteLock() { pthread_rwlock_destroy(&m_stReadWrite); } void rdlock() { pthread_rwlock_rdlock(&m_stReadWrite); } void wrlock() { pthread_rwlock_wrlock(&m_stReadWrite); } void unlock() { pthread_rwlock_unlock(&m_stReadWrite); } private: pthread_rwlock_t m_stReadWrite; }; //自动互斥锁 class MutexLockGuard { public: explicit MutexLockGuard(MutexLock& stMutex) : m_rstMutex(stMutex) { m_rstMutex.lock(); } ~MutexLockGuard(){ m_rstMutex.unlock(); } private: MutexLock& m_rstMutex; }; //可选自动互斥锁 class OptionalMutexLockGuard { public: OptionalMutexLockGuard(MutexLock& stMutex, bool bEnableLock) : m_rstMutex(stMutex),m_bEnableLock(bEnableLock) { if(bEnableLock) m_rstMutex.lock(); } ~OptionalMutexLockGuard() { if(m_bEnableLock) m_rstMutex.unlock(); } private: MutexLock& m_rstMutex; bool m_bEnableLock; }; //读写锁 class CRWLock { public: CRWLock() { pthread_rwlock_init(&m_stRWLock, NULL); } ~CRWLock() { pthread_rwlock_destroy(&m_stRWLock); } int rdlock() { return pthread_rwlock_rdlock(&m_stRWLock); } int wrlock() { return pthread_rwlock_wrlock(&m_stRWLock); } int unlock() { return pthread_rwlock_unlock(&m_stRWLock); } private: pthread_rwlock_t m_stRWLock; }; //自动读写锁 class CRWLockGuard { public: explicit CRWLockGuard(CRWLock &stLock, bool IsReadLock) :m_rstLock(stLock) { if (IsReadLock) { m_iRet = m_rstLock.rdlock(); } else { m_iRet = m_rstLock.wrlock(); } } int GetLockRetVal(){ return m_iRet; } ~CRWLockGuard(){ m_rstLock.unlock(); }; private: CRWLock& m_rstLock; int m_iRet; }; class Condition { public: explicit Condition(MutexLock &mutex) : m_mutex (mutex) { pthread_cond_init(&m_cond, NULL); } ~Condition() { pthread_cond_destroy(&m_cond); } void wait() { m_mutex.lock(); pthread_cond_wait(&m_cond, m_mutex.getMutexPtr() ); m_mutex.unlock(); } int timewait(const struct timespec& timeout) { int result = 0; m_mutex.lock(); result = pthread_cond_timedwait(&m_cond, m_mutex.getMutexPtr() , &timeout); m_mutex.unlock(); return result; } void notify() { pthread_cond_signal(&m_cond); } void notifyAll() { pthread_cond_broadcast(&m_cond); } // 超时时间设置,单位为毫秒 void settimeout(struct timespec *tsp , unsigned int timeout_ms) { struct timeval now; gettimeofday(&now, NULL); tsp -> tv_sec = now.tv_sec; tsp -> tv_nsec = now.tv_usec * 1000 + timeout_ms * 1000 *1000; // 设置新的时间点算超时时间 tsp -> tv_sec += tsp -> tv_nsec/(1000*1000*1000); tsp -> tv_nsec = tsp -> tv_nsec%(1000*1000*1000); } private: pthread_cond_t m_cond; MutexLock& m_mutex; }; } #endif
相关文章推荐
- Linux socket 初步
- Linux Kernel 4.0 RC5 发布!
- linux lsof详解
- linux 文件权限
- Linux 执行数学运算
- 10 篇对初学者和专家都有用的 Linux 命令教程
- Linux 与 Windows 对UNICODE 的处理方式
- Ubuntu12.04下QQ完美走起啊!走起啊!有木有啊!
- 解決Linux下Android开发真机调试设备不被识别问题
- 运维入门
- 运维提升
- Linux 自检和 SystemTap
- Ubuntu Linux使用体验
- c语言实现hashmap(转载)
- Linux 信号signal处理机制
- linux下mysql添加用户
- Scientific Linux 5.5 图形安装教程
- Linux 下无损图片压缩小工具介绍