我试图仅使用互斥锁来实现读/写锁(仅供学习)。正当我以为我已经涵盖了所有极端情况(因为程序可以处理各种组合)时,我意识到,我忽略了一个事实(因为它在 ubuntu 中工作):互斥体应该由线程的所有者释放。下面是我的实现,
class rw_lock_t{
int NoOfReaders;
int NoOfWriters, NoOfWritersWaiting;
pthread_mutex_t class_mutex;
pthread_cond_t class_cond;
pthread_mutex_t data_mutex;
public:
rw_lock_t()
: NoOfReaders(0),
NoOfWriters(0), NoOfWritersWaiting(0)
{
pthread_mutex_init(&class_mutex, NULL);
pthread_mutex_init(&data_mutex, NULL);
pthread_cond_init(&class_cond, NULL);
}
void r_lock()
{
pthread_mutex_lock(&class_mutex);
//while(NoOfWriters!=0 || NoOfWritersWaiting!=0) //Writer Preference
while(NoOfWriters!=0)
{
pthread_cond_wait(&class_cond, &class_mutex);
}
if(NoOfReaders==0)
{
pthread_mutex_unlock(&class_mutex);
pthread_mutex_lock(&data_mutex);
pthread_mutex_lock(&class_mutex);
NoOfReaders++;
pthread_mutex_unlock(&class_mutex);
}
else if(NoOfReaders>0) //Already Locked
{
NoOfReaders++;
pthread_mutex_unlock(&class_mutex);
}
}
void w_lock()
{
pthread_mutex_lock(&class_mutex);
NoOfWritersWaiting++;
while(NoOfReaders!=0 && NoOfWriters!=0)
{
pthread_cond_wait(&class_cond, &class_mutex);
}
pthread_mutex_unlock(&class_mutex);
pthread_mutex_lock(&data_mutex);
pthread_mutex_lock(&class_mutex);
NoOfWritersWaiting--; NoOfWriters++;
pthread_mutex_unlock(&class_mutex);
}
void r_unlock()
{
pthread_mutex_lock(&class_mutex);
NoOfReaders--;
if(NoOfReaders==0)
pthread_mutex_unlock(&data_mutex);
pthread_mutex_unlock(&class_mutex);
pthread_cond_signal(&class_cond);
}
void w_unlock()
{
pthread_mutex_lock(&class_mutex);
NoOfWriters--;
if(NoOfWriters==0)
pthread_mutex_unlock(&data_mutex);
pthread_mutex_unlock(&class_mutex);
pthread_cond_signal(&class_cond);
}
};
我现在的问题是,最好的纠正方法(最小的改变)是什么。信号量绝对是闲置的选择,但我想到的解决方案如下
解决方案#1
1)我将有一个专用线程,只是为了锁定/解锁读取情况下的互斥体。
2) 该线程将等待条件变量以从 r_lock 或 r_unlock 获取信号。
3) r_lock 和 r_unlock 将不再执行“pthread_mutex_lock/unlock(&data_mutex);”,而是向专用线程发出锁定信号。
4)我必须记住这个实现的许多事实,
更新:解决方案#2
1) 进行实际锁定的线程将在全局范围内保留其tid。
2)每当一个线程解锁时都会确保检查与全局tid相等。
3) 如果匹配将等待“NoOfReaders==0”条件并解锁。
那么,有没有更好的方法可以对程序进行修正呢?