利用信号实现写优先的读写锁

  以前利用linux系统提供的读写锁写过一些小程序,但是linux系统提供的读写锁是线程级的,如果是进程间的同步的话,就没那么轻松了。而且由于linux系统提供的读写锁是读优先的,在有些情况下,也不能满足我们的要求。下面就说说利用信号量来实现写优先的读写锁。

 

  先说说原理,这个程序需要用到两个信号量,一个互斥信号量A,一个同步信号量B,其拥有MAX_RESOURCES个资源。当读进程申请读锁的时候,首先查看是否已经有写进程申请了A资源,如果有,则进入阻塞状态,否则,则申请一个B资源,等读操作完成后,再释放B资源。当写进程申请写锁时,首先查询是否已经有其他的写进程已经申请了A资源,如果有,则进入阻塞状态,否则,先申请A资源,然后申请MAX_RESOURCES个B资源,这样,如果有读进程正在执行读操作,那么写进程就会阻塞,直到所有的读进程都释放B资源。通过这样的机制,就保证了这是一个写优先的读写锁。

 

  下面是一些关键代码:

读锁:  

1 //设置读锁
2  _r_lock[0].sem_num = 0; //判断信号量0是否为0
3  _r_lock[0].sem_op = 0;
4 _r_lock[0].sem_flg = 0;
5 _r_lock[1].sem_num = 1; //对信号量1进行P操作
6  _r_lock[1].sem_op = -1;
7 _r_lock[1].sem_flg = SEM_UNDO;
8
9
10  int TestRWLock::TestRLock()
11 {
12 int ret = semop(_sem_fd, _r_lock, 2);
13 return ret;
14 }

 

写锁:

 

1 //设置写锁
2  //判断信号量是否为0,如果是,则对其进行+1操作
3  _w_lock_first[0].sem_num = 0;
4 _w_lock_first[0].sem_flg = 0;
5 _w_lock_first[0].sem_flg = 0;
6 _w_lock_first[1].sem_num = 0;
7 _w_lock_first[1].sem_op = 1;
8 _w_lock_first[1].sem_flg = SEM_UNDO;
9
10 //申请信号量1所有的资源,这样能保证所有的读锁都已经释放资源_w_lock_second.sem_num = 1;
11 _w_lock_second.sem_op = -1 * max_reader;
12 _w_lock_second.sem_flg = SEM_UNDO;
13
14
15 int TestRWLock::TestWLock()
16 {
17 int ret = semop(_sem_fd, _w_lock_first, 2);
18 if(ret >= 0)
19 {
20 ret = semop(_sem_fd, &_w_lock_second, 1);
21 if(ret < 0)
22 {
23 ANGEL_WARN_LOG(0, 0, "加写锁失败");
24 }
25 return ret;
26 } else {
27 ANGEL_WARN_LOG(0, 0, "加写锁失败.");
28 }
29
30 return ret;
31 }

 

 

posted @ 2010-09-24 17:41  MR_H  阅读(4596)  评论(0编辑  收藏  举报