赞
踩
本关任务:利用信号量实现一个读写锁。
Linux 系统中提供了现成的读写锁库函数,也就是上一关我们学习的。其实,我们利用其他线程同步的方法也可以实现一个读写锁。
读写锁 需要满足如下规则:
通过实训"Linux之线程同步一"的学习,我们现在知道如何互斥锁和条件变量来同步线程。那么利用 互斥锁 和 条件变量 知识就可以简单的读写锁。
利用条件变量和互斥锁实现读写锁
使用条件变量和互斥锁实现读写锁,根据读写锁的特性,当有读者在读取数据时,则不能有线程对数据进行写操作,并且同时可以存在多个读者。当有写者在对数据进行写操作的时候,则不能有线程对数据进行读操作,并且同一时刻只能有一个写者。因此,实现一个简单的读写锁可以分为以下几步:
- 1. 定义两个变量用于记录读者(readNum)和写者(writeNum)的个数;
- 2. 对于写模式的加锁,如果readNum和writeNum同时为0,则将writeNum设置为1表示此时有一个写者需要对数据进行写操作;否则,写模式的加锁操作处于等待状态;
- 3. 对于写模式的解锁,如果完成的写操作,此时需要将writeNum设置为0,表示此时没有写操作,并且通知读者可以读取数据了;
- 4. 对于读模式的加锁,如果writeNum为0,则表示当前没有写操作,可以读取数据,并且将readNum值加一表示多了一个读者;否则,读模式的加锁操作处于等待状态;
- 5. 对于读模式的解锁,如果完成的读操作,此时需要将readNum减一操作,然后判断readNum是否为0,如果为零,则通知写者可以执行写操作;
利用互斥锁实现读写锁
只使用互斥锁也可以实现读写锁,详细的步骤可分为以下几步:
- 1. 定义一个变量用于记录读者(readNum)的个数和两个互斥锁,分别是读模式的互斥锁(mutex_read)和写模式的互斥锁(mutex_write);
- 2. 对于写模式的加锁,直接对mutex_write进行加锁操作即可;
- 3. 对于写模式的解锁,直接对mutex_write进行解锁操作即可;
- 4. 对于读模式的加锁,首先判断读者的数量是否为0,如果为0,则表示第一个读者要去读取数据,那么此时要禁止写者进行写数据操作,所以对mutex_write进行加锁操作并设置readNum++;否则直接将readNum++即可;
- 5. 对于读模式的解锁,首先将readNum--,然后判断此时是否readNum为0,如果为0,则表示现在允许写者可以写数据,因此要对mutex_write进行解锁操作;
本关的编程任务是补全右侧代码片段中Begin
至End
中间的代码,具体要求如下:
sem_rwlock_rdlock
和sem_rwlock_unrdlock
函数;sem_rwlock_rdlock
函数用于读模式下的读加锁操作;sem_rwlock_unrdlock
函数用于读模式下的读解锁操作;- #include <stdio.h>
- #include <pthread.h>
- #include <semaphore.h>
-
- //记录读线程的个数
- extern int reader;
-
- //全局的信号量变量
- extern sem_t sem_read, sem_write;
-
- //读写锁初始化函数
- void sem_rwlock_init()
- {
- reader = 0;
- //初始化信号量个1
- sem_init(&sem_read, 0, 1);
- sem_init(&sem_write, 0, 1);
- }
-
- //读写锁注销函数
- void sem_rwlock_destroy()
- {
- sem_destroy(&sem_read);
- sem_destroy(&sem_write);
- }
-
- //读模式下的加锁操作
- void sem_rwlock_rdlock()
- {
- //读模式下加锁操作
- /********** BEGIN **********/
- sem_wait(&sem_read);
- if(reader == 0)
- sem_wait(&sem_write);
- reader++;
- sem_post(&sem_read);
- /********** END **********/
- }
-
- //读模式下的解锁操作
- void sem_rwlock_unrdlock()
- {
- //读模式下解锁操作
- /********** BEGIN **********/
- sem_wait(&sem_read);
- reader--;
- if(reader == 0)
- sem_post(&sem_write);
- sem_post(&sem_read);
- /********** END **********/
- }
-
- //写模式下的加锁操作
- void sem_rwlock_wrlock()
- {
- sem_wait(&sem_write);
- }
-
- //写模式下的解锁操作
- void sem_rwlock_unwrlock()
- {
- sem_post(&sem_write);
- }

Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。