Windows c++中的同步
Synchronization in Windows C++
我需要实现如下系统:1个写入器和3个读取器互斥,但3个读取器可以同时读取。写入器将名为data的共享变量写入一个随机数,读取器必须将其打印到控制台。期望的输出是:我写:7;我读:7;我读:7;我读到:7我写道:1;我读:1;我读:1;我读:1我写的是:9;我读:9;我读:9;我读:9
我在互斥锁m上使用了两个unique_lock和两个condition_variable: cv1用于读取(只有当写入器已经写入时,它们才能读取),cv2用于写入器(只有当所有读取器都已读取时,它才能写入)。
为了保证并行读,在等待之后我解锁,并在执行cout指令后取锁。我认为,作家不能采取锁,因为当他们正在读取,他是在等待,条件opDone == 3是无效的。
相反,输出是:我写道:1我读:1我读:我读:1我读:1我读:11
这是代码:
// 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();
}
}
如果我在读取之前没有解锁(),代码将完美运行,但这样读取操作不是并行的。任何建议吗?
看一下原子变量的初始化。例如,Clang会显示一个警告。
volatile atomic_int opDone = 0;
// error: copying variable of type 'atomic_int' (aka '__atomic_base') invokes deleted constructor
工作草案(当前的N4527)在§8.5.15中规定了以下内容。
初始化以的=形式发生大括号或等号初始化器或条件(6.4),以及in参数传递,函数返回,抛出异常(15.1),处理异常(15.3)和聚合成员初始化(8.5.1),是叫copy-initialization 。[注:复制初始化可能会调用(12.8)。
原因是你不能复制原子。所有的加载和存储都必须通过显式调用进行。对以下方法的修复应该可以解决这个问题:
static atomic_int opDone(0);
相关文章:
- 松弛原子与无同步情况下的记忆连贯性
- 使用QQuickFramebufferObject时同步数据的最佳方式是什么
- 在C++中同步线程
- 与 stdio 同步是否使程序 I/O 非交互式?
- 如何在qt中同步应用程序和显示器的刷新率?
- Windows 进程间同步类似事件?
- 当对套接字 send() 的同步调用由于连接另一端丢失而被阻止时,如何恢复?
- 将 10 个线程与原子布尔值同步
- ofstream::close() 是否在 Linux 上调用同步?
- 与Visual Studios(c ++)同步时如何组织github存储库?
- 原子获取是否与互斥锁释放同步?
- Boost (Beast) websocket:同步写入挂起
- Postgres vs MySQL:命令不同步;.
- 线程过程中的线程同步问题
- 同步读取多个 TCP 响应
- 同步两个具有不同帧速率的传感器
- 如何定期同步线程?
- 同步对多个向量进行排序
- 同步类中的公共变量
- 如何检查 ntpd 是否仍在运行和同步