Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/git/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 读写互斥体_C_Mutex - Fatal编程技术网

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