Windows C ++中的同步

乔22

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

我在互斥锁m上使用了两个unique_lock和两个condition_variables:用于读者的cv1(仅在作家已经写过的情况下才可以读取)和用于作家的cv2(可以在所有读者都读过的情况下才可以写)。

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

相反,输出为:我写:1我读:1我读:我读:1我读:1我读:1 1

这是代码:

// 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();
    }
}

如果我在读取之前不解锁(),则代码可以完美运行,但是通过这种方式,读取操作不是并行的。有什么建议吗?

你好世界

看一下原子变量的初始化。例如发出警告。

volatile atomic_int opDone = 0;
// error: copying variable of type 'atomic_int' (aka '__atomic_base') invokes deleted constructor

工作草案(当前为N4527)在第8.5.15节中规定了以下内容。

大括号或等于初始化器或条件(6.4)的=形式进行的初始化,以及参数传递,函数返回,引发异常(15.1),处理异常(15.3)和聚合成员的形式初始化(8.5.1)称为复制初始化[注意:复制初始化可能会调用移动(12.8)。—尾注]

原因是您无法复制原子。所有加载和存储都必须通过显式调用进行。对以下方法的修复应解决此问题:

static atomic_int opDone(0);

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何在Windows Service C#中的方法中同步执行所有语句

来自分类Dev

C#网络中的同步

来自分类Dev

在C#中同步线程

来自分类Dev

C中的同步回调

来自分类Dev

C ++ / Windows多线程同步/数据共享

来自分类Dev

在Windows脚本中同步Internet时间?

来自分类Dev

C#/ C ++中的同步并行处理

来自分类Dev

在Objective-C中同步异步任务

来自分类Dev

C#中的同步任务执行

来自分类Dev

在C#中同步闪烁标签

来自分类Dev

C#中的同步任务队列

来自分类Dev

监视C中同步线程的源代码

来自分类Dev

在C#中同步繁重的任务

来自分类Dev

C ++中的多线程数据同步

来自分类Dev

C ++ 11中与std :: atomic的同步

来自分类Dev

C#中的同步任务队列

来自分类Dev

在异步C#中同步执行

来自分类Dev

在C#中同步缓冲区

来自分类Dev

基于异步/等待的Windows服务中的同步I / O

来自分类Dev

如何查看SkyDrive是否仍在Windows 8.1中同步?

来自分类Dev

在Windows中以递归方式删除文件夹同步模式

来自分类Dev

在Windows 10中禁用同步时钟不起作用

来自分类Dev

如何在Windows中同步网络文件夹?

来自分类Dev

WebRTC Android-Windows中的gclient同步错误

来自分类Dev

如何同步从Java传递到C ++的C ++中的Java对象?

来自分类Dev

在Windows中安装C ++的libcurl

来自分类Dev

信号量C#对象同步方法是从未同步的代码块中调用的

来自分类Dev

如何正确同步对Objective-C中的实例变量的访问

来自分类Dev

在C#中同步共享资源的集合