我试图仅使用互斥锁实现读写锁(只是为了学习),在程序可以处理各种情况的基础上,当我认为已经覆盖了所有角落时,我意识到一点重要的事实:(它在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);
}
};
我的问题是,最小的更改方式是什么。Semaphore 绝对是最佳选择,但我想到以下解决方案:
解决方案#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" 条件并解锁它。
那么,是否有更好的方法可以纠正程序呢?