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

一、锁的概述

1.互斥锁

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

2.读写锁

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

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

3.自旋锁

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

4.递归锁

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

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


二、diy数据库中锁的实现

#ifndef OSSLATCH_HPP__
#define OSSLATCH_HPP__

#include "core.hpp"


#define oss_mutex_t					pthread_mutex_t
#define oss_mutex_init					pthread_mutex_init
#define oss_mutex_destroy				pthread_mutex_destroy
#define oss_mutex_lock					pthread_mutex_lock
#define oss_mutex_trylock(__lock)	(pthread_mutex_trylock( (__lock) ) == 0 )
#define oss_mutex_unlock				pthread_mutex_unlock

#define oss_rwlock_t					pthread_rwlock_t
#define oss_rwlock_init					pthread_rwlock_init
#define oss_rwlock_destroy				pthread_rwlock_destroy
#define oss_rwlock_rdlock				pthread_rwlock_rdlock
#define oss_rwlock_rdunlock				pthread_rwlock_unlock
#define oss_rwlock_wrlock				pthread_rwlock_wrlock
#define oss_rwlock_wrunlock				pthread_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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值