首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Windows C++中的同步

Windows C++中的同步
EN

Stack Overflow用户
提问于 2015-09-05 16:54:22
回答 1查看 83关注 0票数 0

我需要实现以下系统:1作者和3位读者互斥,但3位读者可以同时阅读。作者在一个名为dato的共享变量上写入一个随机数,读取器必须将其打印到控制台。预期的输出是:我写了: 7;我读:7;我读:7;我读:7;我读: 1;我读:1;我读:1;我读:1;我读:1我写: 9;我读:9;我读:9;我读:9;我读:9;我读:9;我读:9;我读:9;我读:9;我读:9;我读:9。

我在互斥对象m上使用了两个unique_lock,在读取器上使用了两个condition_variables: cv1 (只有在作者已经写好的情况下才能读到),而对于作者则使用了cv2 (只要所有的读者都读过,它就可以写)。

为了保证并行读取,在等待之后,我解锁,并在cout指令之后取锁。我认为作者无法接受锁,因为当他们阅读时,他在等待,而条件opDone == 3无效。

相反,我的输出是:我写:1我读:1我读:1我读:1

这是代码:

代码语言:javascript
复制
// nreader1writer.cpp : Defines the entry point for the console application.

#include "stdafx.h"

condition_variable cv1, cv2;
mutex m;
volatile atomic_int opDone = 0;
volatile atomic_bool iWrote = false;
volatile atomic_bool flag = false;

volatile atomic_int dato;

void writer();
void reader();

int _tmain()
{
    thread t1(reader);
    thread t2(reader);
    thread t3(reader);
    thread t4(writer);

    t1.join();
    t2.join();
    t3.join();
    t4.join();
    return 0;
}

void writer() {
    unique_lock <mutex> ulw (m, defer_lock);
    while (opDone.load() != 3); //In this way, writer starts just when all readers are already waiting 
    ulw.lock();
    opDone.store(0);
    iWrote.store(false);

    while (1) { 
        dato.store( (int) rand()%10);
        cout << "I wrote: " << dato.load() << endl;
        iWrote.store(true);
        cv1.notify_all();
        cv2.wait(ulw, []() {
            return (opDone.load() == 3);
        });
        opDone.store(0);
        iWrote.store(false);
    }
}

void reader() {
    unique_lock <mutex> ulr (m, defer_lock);
    ulr.lock();
    opDone.fetch_add(1);

    while (1) {
        cv1.wait(ulr, []() {
            return (iWrote.load() == true && opDone.load() < 3);
        });
        ulr.unlock();
        cout << "I read: " << dato << endl;
        ulr.lock();
        opDone.fetch_add(1);
        cv2.notify_one();
    }
}

如果在读取之前不解锁(),代码就会完美地运行,但是这样读取操作就不是并行的。有什么建议吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-09-05 17:09:59

看看原子变量的初始化。例如,Clang就会发出警告。

代码语言:javascript
复制
volatile atomic_int opDone = 0;
// error: copying variable of type 'atomic_int' (aka '__atomic_base') invokes deleted constructor

工作草案(目前的N4527)在第8.5.15节中作了如下说明。

在=形式的brace-or-equal-initializer或条件(6.4)以及在参数传递、函数返回、抛出异常(15.1)、处理异常(15.3)和聚合成员初始化(8.5.1)中发生的初始化,称为复制初始化()。注意:复制初始化可以调用移动(12.8)。-尾注

原因是你不能复制原子。所有负载和存储必须与显式调用一起进行。对以下方法的修复应该解决这个问题:

代码语言:javascript
复制
static atomic_int opDone(0);
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32415552

复制
相关文章

相似问题

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