C 读写互斥体
这就是读写一致性的读写器问题。 以下是算法:C 读写互斥体,c,mutex,C,Mutex,这就是读写一致性的读写器问题。 以下是算法: void reader() { while (1) { P(mutex); rc++; if (rc == 1) P(db); /* <---- A */ V(mutex); /* <---- B */ read_data_base(); P(mutex); rc--; V(mutex);
void reader() {
while (1) {
P(mutex);
rc++;
if (rc == 1) P(db); /* <---- A */
V(mutex); /* <---- B */
read_data_base();
P(mutex);
rc--;
V(mutex);
if (rc == 0) V(db);
}
}
void writer() {
while (1) {
P(db);
write_data_base();
V(db);
}
}
void读取器(){
而(1){
P(互斥);
rc++;
如果(rc==1)P(db);/*首先,代码是错误的:您需要在锁定的
互斥锁下执行if(rc==0)V(db)
需要行A来锁定数据库进行读取。锁在第一次读取操作时设置,在最后一次读取操作后释放;在每次可能的写入操作中都会设置锁。如果不设置锁,则读写操作可能同时执行,从而导致数据损坏。首先,代码错误:如果(rc==0)V(db)
处于锁定的互斥锁下,则需要执行
需要行A来锁定数据库进行读取。锁在第一次读取操作时设置,在最后一次读取操作后释放;在每个可能的写入操作期间都会设置锁。如果不设置锁,则可能同时执行读取和写入操作,从而导致数据损坏。
- 第A行的目的是检查当前读卡器是否是写入后的第一个读卡器(或总体上的第一个读卡器)。如果是这种情况,则他必须获得数据库互斥锁(db),以便在至少有一个读卡器读取数据库时,没有写入器可以写入数据库
最后一个读卡器的对应行是:
if(rc==0)V(db);
此行的目的是检查当前读卡器是否是最后一个读卡器,以便写入程序可以进入下一个读卡器(如果没有其他读卡器在写入程序之前进入)
- 根据以上描述,如果删除行A,代码将无法正常工作
注意:从下面Vlad的回答(以及评论中的讨论)可以看出,V(互斥)
应该在之后,如果(rc==0)V(db)
- 第A行的目的是检查当前读卡器是否是写入后的第一个读卡器(或总体上的第一个读卡器)。如果是这种情况,则他必须获得数据库互斥锁(db),以便在至少有一个读卡器读取数据库时,没有写入器可以写入数据库
最后一个读卡器的对应行是:
if(rc==0)V(db);
此行的目的是检查当前读卡器是否是最后一个读卡器,以便写入程序可以进入下一个读卡器(如果没有其他读卡器在写入程序之前进入)
- 根据以上描述,如果删除行A,代码将无法正常工作
注意:从下面弗拉德的回答(以及评论中的讨论)中可以看出,V(互斥)
应该在之后,如果(rc==0)V(db)
,作者不应该在任何人阅读时写作。因此,任何读者在阅读时都会阻止db,如果他是早起的人(#1)。如果他是房间里最后一个人(rc==0),他也必须清除封锁。作者不应该在任何人阅读时写作。因此,如果他是早起的人(#1),任何读者在阅读时都会阻塞db。如果他是房间里最后一个人(rc==0),他必须清除封锁还有。你确定代码是错的吗?你能告诉我一个例子,哪里会发生错误吗?我也认为它是错的。线程1://假设rc==0v(互斥);切换到线程2:p(互斥);rc++;//现在rc==1切换到线程1:if(rc==0)V(db);//rc已经是1,所以它忘记了V(db)当然。假设读卡器#1以线程#1的形式出现,并在(rc==0)V(db);
的情况下一直执行到行(但不包括它)。现在上下文切换到线程2。在线程2中,另一个读卡器来了,锁定互斥锁,增加rc
,现在rc
的值是2。因此,第二个读卡器不会锁定db
。现在上下文切换到线程3,在这个线程中,编写器尝试锁定db,获得锁,并修改所需的数据当前正在被线程2读取。因此数据将被破坏。@Vlad:虽然我的评论迟了两年,但如果reader#1达到您所说的那一行,它将已经减少了rc
,因此在reader#2进入之前它的值为0,之后它的值为1。@3electrologos:好的,进一步微调:)(1)rc==0
(2)线程1中的读卡器执行到if(rc==0)
,现在db
被锁定,mutex
未被锁定。(3)线程2中的读卡器执行到if(rc==1)
,现在rc==1
,db
仍然被锁定(由线程1中的读卡器锁定),并且mutex
也被锁定。(4)线程1中的读取器执行if(rc==0)V(db)
。当rc!=0
时,这不会执行任何操作。(5)线程2中的读取器继续执行if(rc==1)P(db)
。这将永远等待,db
已经锁定。你确定代码是错误的吗?你能告诉一个例子,哪里会发生错误吗?我也认为它是错误的。线程1://假设rc==0 V(互斥体);切换到线程2:P(互斥体);rc++;//现在rc==1切换到线程1:if(rc==0)V(db);//rc已经是1,所以它忘记了V(db)。当然。假设一个读卡器#1进入线程#1,如果(rc==0)V(db);
(但不包括它),则执行到第行。现在上下文切换到线程2。在线程2中,另一个读卡器来了,锁定互斥锁,增加rc
,现在rc
的值是2。因此,第二个读卡器不会锁定db
。现在上下文切换到线程3,在这个线程中,编写器尝试锁定db,获得锁,并修改所需的数据线程#2当前正在读取数据。因此数据将被破坏。@Vlad:虽然我发表此评论晚了两年,但如果reader#1达到您所说的行,它将已经减少了rc
,因此其值将为0