我试图只使用互斥锁来实现读/写锁(仅用于学习)。正当我想我已经覆盖了所有的角落案例(因为程序使用了各种组合),我已经意识到,我忽略了这个事实(因为它在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)我要记住许多事实对于此实现,
的信令和实际锁定是两个不同的事件,因此可能需要同步。
将需要一个互斥+ condVariable +线程和更多的同步额外。
更新:解决方案2
1)谁做实际的锁定将保持其全球范围的TID线程。 2)每当线程解锁将确保与全局tid检查相等。 3)如果匹配将等待“NoOfReaders == 0”条件并解锁它。
那么,有没有更好的方法可以纠正程序。
使用条件,它不只是互斥。 – Alexandru 2013-01-10 21:55:25
这是一个非常好的答案。没有家庭作业请! – Kobor42 2013-11-19 12:11:31
我们不应该检查r_lock()和w_lock()函数中的虚假唤醒条件吗?这是来自manpage:“当使用条件变量时,总是有一个布尔谓词涉及到与每个条件相关的共享变量,如果线程应该继续执行,则等待为真,可能会发生从pthread_cond_timedwait()或pthread_cond_wait()函数的虚假唤醒。 pthread_cond_timedwait()或pthread_cond_wait()的返回并不意味着这个谓词的值有任何意义,应该在返回时重新评估谓词。“ --->如果返回false,则返回循环! – cforfun 2016-02-16 02:29:39