您的位置:首页 > 运维架构 > Linux

[转]Linux 下的线程读写锁 - 空穴来风 - C++博客

2007-11-05 12:04 666 查看
导读:
  有一种写优先读写锁,有如下特点:
  1)多个读者可以同时进行读
  2)写者必须互斥(只允许一个写者写,也不能读者写者同时进行)
  3)写者优先于读者(一旦有写者,则后续读者必须等待,唤醒时优先考虑写者)
  在Solaris 中直接提供了读写锁, 但是在Linux 中只提供了线程的读写锁, 这里记录了一些读写锁的资料.
  1.Solaris .vs. Linux Posix 库函数
  Solaris 库(lib 线程) Linux POSIX 库(libp 线程) 操作
  sema_destroy() sem_destroy() 销毁信号状态。
  sema_init() sem_init() 初始化信号。
  sema_post() sem_post() 增加信号。
  sema_wait() sem_wait() 阻止信号计数。
  sema_trywait() sem_trywait() 减少信号计数。
  mutex_destroy() pthread_mutex_destroy() 销毁或禁用与互斥对象相关的状态。
  mutex_init() pthread_mutex_init() 初始化互斥变量。
  mutex_lock() pthread_mutex_lock() 锁定互斥对象和块,直到互斥对象被释放。
  mutex_unlock() pthread_mutex_unlock() 释放互斥对象。
  cond_broadcast() pthread_cond_broadcast() 解除对等待条件变量的所有线程的阻塞。
  cond_destroy() pthread_cond_destroy() 销毁与条件变量相关的任何状态。
  cond_init() pthread_cond_init() 初始化条件变量。
  cond_signal() pthread_cond_signal() 解除等待条件变量的下一个线程的阻塞。
  cond_wait() pthread_cond_wait() 阻止条件变量,并在最后释放它。
  rwlock_init() pthread_rwlock_init() 初始化读/写锁。
  rwlock_destroy() pthread_rwlock_destroy() 锁定读/写锁。
  rw_rdlock() pthread_rwlock_rdlock() 读取读/写锁上的锁。
  rw_wrlock() pthread_rwlock_wrlock() 写读/写锁上的锁。
  rw_unlock() pthread_rwlock_unlock() 解除读/写锁。
  rw_tryrdlock() pthread_rwlock_tryrdlock() 读取非阻塞读/写锁上的锁。
  rw_trywrlock() pthread_rwlock_trywrlock() 写非阻塞读/写锁上的锁。
  2.使用mutex 来实现
  设置三个互斥信号量:
  rwmutex?? ??? ?用于写者与其他读者/写者互斥的访问共享数据
  rmutex?? ??? ?用于读者互斥的访问读者计数器readcount
  nrmutex?? ??? ?用于写者等待已进入读者退出,所有读者退出前互斥写操作
  var?? rwmutex,rmutex,nrmutex:semaphore:=1,1,1; ?
  int?? readcount=0;
  cobegin
  ?reader begin
  ? ?P(rwmutex);
  ? ?P(rmutex);
  ? ?readcount++;
  ? ?if (readcount == 1) P(nrmutex);? //有读者进入,互斥写操作
  ? ?V(rmutex);
  ? ?V(rwmutex);? //及时释放读写互斥信号量,允许其它读、写进程申请资源读数据;
  ? ?
  ? ?P(rmutex);
  ? ?readcount--;
  ? ?if(readcount == 0) V(nrmutex);? //所有读者退出,允许写更新
  ? ?V(rmutex);
  ?End
  ? ?writer begin
  ? ?P(rwmutex);??? //互斥后续其它读者、写者
  ? ?P(nrmutex);??? //如有读者正在读,等待所有读者读完
  ? ?写更新;
  ? ?V(nrmutex);??? //允许后续新的第一个读者进入后互斥写操作 ?
  ? ?V(rwmutex);??? //允许后续新读者及其它写者
  ?End ?
  coend??
  3. 利用pthread_cond_* &pthread_mutex_* 实现rw_lock
  #include?#include?#include?#include?
  using?namespace?std;class?RWLock?{private?:
  pthread_mutex_t?cnt_mutex;
  pthread_cond_t?rw_cond;
  int?rd_cnt,?wr_cnt;
  RWLock(const?RWLock&);
  RWLock&?operator=?(const?RWLock&);public?:
  RWLock():?rd_cnt(0),wr_cnt(0)
  {
  pthread_mutex_init(&cnt_mutex,?NULL);
  pthread_cond_init(&rw_cond,?NULL);
  }
  void?get_shared_lock()
  {
  pthread_mutex_lock(&cnt_mutex);
  while?(wr_cnt?>0)
  {
  pthread_cond_wait(&rw_cond,&cnt_mutex);
  }
  rd_cnt++????????????pthread_mutex_unlock(&cnt_mutex);
  }
  void?release_shared_lock()
  {
  pthread_mutex_lock(&cnt_mutex);
  rd_cnt--????????????if?(0?==?rd_cnt)
  {
  pthread_cond_signal(&rw_cond);
  }
  pthread_mutex_unlock(&cnt_mutex);
  }
  void?get_exclusive_lock()
  {
  pthread_mutex_lock(&cnt_mutex);
  while?(rd_cnt+wr_cnt>0)
  {
  pthread_cond_wait(&rw_cond,&cnt_mutex);
  }
  wr_cnt++????????????pthread_mutex_unlock(&cnt_mutex);
  }
  void?release_exclusive_lock()
  {
  pthread_mutex_lock(&cnt_mutex);
  wr_cnt--????????????pthread_cond_broadcast(&rw_cond);
  pthread_mutex_unlock(&cnt_mutex);
  }
  ~RWLock()
  {
  pthread_mutex_destroy(&cnt_mutex);
  pthread_cond_destroy(&rw_cond);
  }
  };class?Test
  {private?:????
  RWLock?lock????
  static?void*?shared_task_handler(void*?arg)
  {
  Test*?testptr?=?static_cast(arg);
  testptr->lock.get_shared_lock();
  //do?the?shared?task?here
  testptr->lock.release_shared_lock();
  }
  static?void?*?exclusive_task_handler(void?*?arg)
  {
  Test*?testptr?=?static_cast(arg);
  testptr->lock.get_exclusive_lock();
  //do?the?exclusive?task?here
  testptr->lock.release_exclusive_lock();
  }public?:
  typedef?void*?(*ThreadFunc)?(void*);
  void?start()
  {
  srand(time(NULL));
  const?int?THREADS_NO=rand()%100????????????pthread_t*?threads?=?new?pthread_t[THREADS_NO];
  for(int?i=0?i  {
  ThreadFunc?tmpfunc?=?rand()%2??shared_task_handler?:?exclusive_task_handler;
  if?(pthread_create(threads+i,NULL,tmpfunc,this))
  {
  cerr?<
  exit(1);
  }
  }
  for(int?i=0?i  {
  pthread_join(threads[i],NULL);
  }
  delete[]?threads;
  }
  };int?main()
  {
  Test?tmptest;
  tmptest.start();
  }

本文转自
http://www.cppblog.com/bigsml/archive/2006/09/07/12137.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: