diy数据库(四)--锁和队列

来源:互联网 发布:优化服务指导意见 编辑:程序博客网 时间:2024/06/06 05:32

一、锁的概述

1.互斥锁

      用来保证临界资源被互斥访问。

2.读写锁

      在一个线程中,当一个读写锁中的读锁被申请后,其他线程可以再申请读锁,但不能申请写锁。

      在一个线程中,当一个读写锁中的写锁被申请后,其他线程不能申请读锁,也不能申请写锁。

3.自旋锁

      等待条件时,不让出cpu。nginx中由于每个工作进程要求快速响应用户,就用到了自选锁。

4.递归锁

      同一个线程可以对一个递归锁加锁多次(其他锁没有这样的功能),但必须解锁同样多次。

另外,主要通过条件变量和信号量来进行线程间同步。


二、diy数据库中锁的实现

#ifndef OSSLATCH_HPP__#define OSSLATCH_HPP__#include "core.hpp"#define oss_mutex_tpthread_mutex_t#define oss_mutex_initpthread_mutex_init#define oss_mutex_destroypthread_mutex_destroy#define oss_mutex_lockpthread_mutex_lock#define oss_mutex_trylock(__lock)(pthread_mutex_trylock( (__lock) ) == 0 )#define oss_mutex_unlockpthread_mutex_unlock#define oss_rwlock_tpthread_rwlock_t#define oss_rwlock_initpthread_rwlock_init#define oss_rwlock_destroypthread_rwlock_destroy#define oss_rwlock_rdlockpthread_rwlock_rdlock#define oss_rwlock_rdunlockpthread_rwlock_unlock#define oss_rwlock_wrlockpthread_rwlock_wrlock#define oss_rwlock_wrunlockpthread_rwlock_unlock#define oss_rwlock_rdtrylock(__lock)(pthread_rwlock_tryrdlock( (__lock) ) == 0 )#define oss_rwlock_wrtrylock(__lock)(pthread_rwlock_trywrlock ( ( __lock) ) == 0 )enum OSS_LATCH_MODE{   SHARED ,//共享   EXCLUSIVE//互斥} ;class ossXLatch//互斥锁{private :   oss_mutex_t _lock ;public :   ossXLatch ()   {      oss_mutex_init ( &_lock, 0 ) ;   }   ~ossXLatch ()   {oss_mutex_destroy(&_lock);   }   void get ()   {oss_mutex_lock(&_lock);   }   void release ()   {oss_mutex_unlock(&_lock);   }   bool try_get ()   {return oss_mutex_trylock(&_lock);   }} ;class ossSLatch//共享锁{private :   oss_rwlock_t _lock ;public :   ossSLatch ()   {      oss_rwlock_init ( &_lock, 0 ) ;   }   ~ossSLatch ()   {      oss_rwlock_destroy ( &_lock ) ;   }   void get ()//写锁   {      oss_rwlock_wrlock ( &_lock ) ;   }   void release ()   {      oss_rwlock_wrunlock ( &_lock ) ;   }   bool try_get ()   {      return ( oss_rwlock_wrtrylock ( &_lock ) ) ;   }   void get_shared ()//读锁   {      oss_rwlock_rdlock ( &_lock ) ;   }   void release_shared ()   {      oss_rwlock_rdunlock ( &_lock ) ;   }   bool try_get_shared ()   {      return ( oss_rwlock_rdtrylock ( &_lock ) ) ;   }} ;#endif

(1)这里的互斥锁和共享锁分别是对操作系统中的互斥锁和读写锁的简单封装

(2)对系统调用用宏定义取别名,体现了oss层对平台相关系统调用的封装的思想

(3)我们的数据库是用线程池的框架,本身要求有线程切换,所以不必用自旋锁来提高效率


三、队列的概述

#ifndef OSSQUEUE_HPP__#define OSSQUEUE_HPP__#include <queue>#include <boost/thread.hpp>#include <boost/thread/thread_time.hpp>#include "core.hpp"template<typename Data>class ossQueue{private :   std::queue<Data> _queue ;//队列   boost::mutex _mutex ;//互斥锁   boost::condition_variable _cond ;//条件变量public :   unsigned int size ()//队列大小   {      boost::mutex::scoped_lock lock ( _mutex ) ;//加锁      return (unsigned int)_queue.size () ;   }   void push ( Data const &data )//压入静态数据   {      boost::mutex::scoped_lock lock ( _mutex ) ;      _queue.push ( data ) ;      lock.unlock () ;//解锁      _cond.notify_one () ;//唤醒一个等待条件变量的线程   }   bool empty () const   {      boost::mutex::scoped_lock lock ( _mutex ) ;      return _queue.empty () ;   }   bool try_pop ( Data &value )//尝试弹出   {      boost::mutex::scoped_lock lock ( _mutex ) ;      if ( _queue.empty () )         return false ;      value = _queue.front () ;      _queue.pop () ;      return true ;   }   void wait_and_pop ( Data &value )//等待并且弹出   {      boost::mutex::scoped_lock lock ( _mutex ) ;      while ( _queue.empty () )      {         _cond.wait ( lock ) ;//等待的时候会释放锁,条件发生后就会得带锁      }      value = _queue.front () ;      _queue.pop () ;   }   bool timed_wait_and_pop ( Data &value, long long millsec )   {      boost::system_time const timeout = boost::get_system_time () +            boost::posix_time::milliseconds(millsec) ;      boost::mutex::scoped_lock lock ( _mutex ) ;      // if timed_wait return false, that means we failed by timeout      while ( _queue.empty () )      {         if ( !_cond.timed_wait ( lock, timeout ) )//带有超时时间的去等待条件         {            return false ;         }      }      value = _queue.front () ;      _queue.pop () ;      return true ;   }} ;#endif

(1)多线程中的消息队列是共享资源,所以在对队列进行操作时必须加锁

(2)线程间的同步主要用条件变量来实现,值得注意的是条件变量的使用一定伴随着一个互斥锁

(3)这里用到了boost中的互斥锁和条件变量,但实际上使用博文《实现一个线程池》中的互斥锁和条件变量包装类也可以。



0 0
原创粉丝点击