首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >并发读写

并发读写
EN

Stack Overflow用户
提问于 2017-05-25 06:36:33
回答 1查看 4.9K关注 0票数 0

下面是我的代码,在回调时更新两个变量,每50 my调用一次。还有一个读取器线程,它每隔50 is就唤醒一次并读取变量。

在遍历之后,我猜会出现这样的情况:读取的线程在收到回调时就会醒来,而且由于我在读取和写入时没有锁定同一个互斥体,在这种情况下,它将导致读取不一致的内存。

但是,当我运行它时,这种情况永远不会发生。是因为我没有运行足够长的时间,还是我的理解有任何错误?

代码语言:javascript
复制
recursive_mutex mutex1
recursive_mutex mutex2
var1, var2

//called every 50ms
onUpdateListener() {
    lock(mutex1)
    update var1
    update var2
}

VarReaderThread::readVar() {
    sleep(50)
    while(true) {
        {
        lock(mutex2)
        read var1
        read var2
        sleep(50)
        }
   }
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-05-25 08:55:17

当两个或多个线程正在访问共享数据时发生数据竞争,其中至少一个线程是写入操作,其中一个或多个线程可能遇到不一致的状态。

提供的代码有两个互斥体,一个用于读,一个用于写。这绝不排除线程读取共享数据(示例中的var1var2 ),而另一个线程正在写入它们,或者更精确地说,是在一个线程开始对其中一个线程进行写入之后,在完成对另一个线程的写入之前,在这样的情况下,该中间状态将被认为是代码逻辑参数及其用途中的不一致状态。

只有一个mutex才能使读写成为排他性的。顺便说一句,还不清楚为什么要声明递归互斥。只有当给定的线程可能遇到要求它获得它已经持有的互斥体的代码时,才需要这样做。在可能的情况下设计并编写代码是更好的设计。

已经引入了显式的unlock步骤,这些步骤可能是显式的,也可能不是显式的,具体取决于编码模型(在C中需要使用,在C++中使用std::lock_guard,在C++中使用synchronized,或者在Java中使用finally等等)。

引入了一些条件,指出了一个合适的终止条件。while(true)是一种糟糕的做法,除非有其他条件会优雅地终止它。

更复杂的模型可能使用“共享互斥”,其中多个线程可以在“读取”模式下保存它,但只有一个线程在“写”模式下保存它。这可能需要一些信号,也可能不需要一些信号,以确保“写”不会进入一个实时锁,在这个锁中,许多读者会无休止地阻止“写”访问。

代码语言:javascript
复制
mutex mutex_v1_v2 //The mutex controlling shared state var1, var2.
var1, var2

//called every 50ms
onUpdateListener() {
    lock(mutex_v1_v2)
    update var1
    update var2
    unlock(mutex_v1_v2)
}

VarReaderThread::readVar() {
    sleep(50)
    while(!finished) {
        lock(mutex_v1_v2)
        read var1
        read var2
        unlock(mutex_v1_v2)
        sleep(50) //V. V. important to sleep not holding the mutex!
   }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44173864

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档