利用进程信号量实现读写锁

static struct sembuf hms_rl[2]   = { {0, -1, SEM_UNDO}, {0, 2, SEM_UNDO} 
static struct sembuf hms_wl[2]   = { {0, -1, SEM_UNDO}, {0, 0, SEM_UNDO} };
static struct sembuf hms_url[1]  = { {0, -1, SEM_UNDO} };
static struct sembuf hms_uwl[1]  = { {0, 1,  SEM_UNDO} };
static struct sembuf hms_init[1] = { {0, 1} };

int hms_lock_read(int semid)
{
/*
1. 申请读锁时,首先做P(1)操作,确保当前没有其他进程在进行写操作;
   然后做V(2)操作,最终实际是对信号量做V(1)操作.
2. 如果被信号打断,则再次获取锁,否则返回失败。
3. 从实际对信号量的V(1)操作可以看出,该读写锁是读者优先的。
4. 该信号量的取值范围是[0 - 同时调用hms_lock_read()的进程数+1]。
5. 写者优先锁:将hms_rl和hms_wl,hms_url和hms_uwl的定义互换即可。
6. 读锁可申请成功的条件是:当前信号量的值大于或等于1.
*/ 
       while (semop(semid, hms_rl, 2) == -1) {
              if (errno == EINTR) {
                     continue;              
              } else {
                     return -1;
              }
       }
       return 0;
}

int hms_lock_write(int semid)
{
/*
1. 申请写锁时,首先做P(1)操作,确保当前没有其他进程在进行写操作;
   然后做P(0)或V(0)操作,判断信号量的值是否为0,即确认没有进程在进行读操作.
2. 如果被信号打断,则再次获取锁,否则返回失败。
3. 写锁可申请成功的条件是:
   3.1 当前信号量的值等于1.
   3.2 或者说:只有当所有的读锁都释放后,且没有其他进程获取的写锁,本次写锁才会申请成功。
*/ 
       while (semop(semid, hms_wl, 2) == -1) {
              if (errno == EINTR) {
                     continue;
              } else {
                     return -1;
              }
       }
       return 0;
}

void hms_unlock_read(int semid)
{
/*
1. 释放读锁时,做P(1)操作.
*/ 
       semop(semid, hms_url, 1);
}

void hms_unlock_write(int semid)
{
/*
1. 释放写锁时,做V(1)操作,用于通知后续的读或写操作,当前有资源存在。
*/ 
       semop(semid, hms_uwl, 1);
}

int hms_init_rwlock(int key)
{
/*
1. 初始化锁资源值为1.
*/ 
       int semid;
       if ((semid = semget(key, 1, IPC_CREAT | IPC_EXCL | 1023)) == -1) {
              if (errno != EEXIST)
                     return -1;
              if ((semid = semget(key, 1, 0)) == -1)
                     return -1;
       } else {
              semop(semid, hms_init, 1);
       }
       return semid;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值