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

  以前利用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 @   MR_H  阅读(4600)  评论(0编辑  收藏  举报
编辑推荐:
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架
点击右上角即可分享
微信分享提示