数据与C++ std::future竞争.编译器重新排序
Data race with C++ std::future. Compiler reorder
我正在编写一个异步访问数据库的应用程序。在我的示例中,序列化由handleAllGroups
函数处理。此函数需要一个函子,它实际上适用于数据库对象。由于我对返回的类型不满意,因此将所有内容包装在延迟异步调用中,以创建我想要的内容。一切似乎都很顺利。我仍然有点担心数据竞争,因为我没有原子或互斥保护。
问:编译器是否可能决定在fut.wait()
之前执行std::move(*data)
?这很重要,因为数据是与其他线程共享的!(ftor 获取共享所有权,并通过 handleAllGroups 在数据库线程中调用)
任何帮助不胜感激!
handleGroupCol_ftor
make_getGroupNamesFtor(std::shared_ptr<std::vector<std::string>>& data);
std::future<MayBeStrVector>
getAllGroupNames()
{
// FIXME: This function is fine, but relies on ftor not
// sharing ownership of data in other places (the move)
auto data = std::make_shared<std::vector<std::string>>();
auto ftor = make_getGroupNamesFtor(data);
return std::async(std::launch::deferred,
[data](std::future<result>&& fut)->MayBeStrVector{
fut.wait();
return {fut.get(), std::move(*data)};
},
handleAllGroups(ftor));
}
假设所有写入data
指向另一个线程的内容都是在制作之前排序的 - fut
- 就绪,你是安全的。[futures.state]/p9:
调用成功设置共享存储结果的函数 与函数的 (1.10) 调用成功同步状态 检测由该设置生成的就绪状态。的储存 结果(无论是正常还是异常)进入共享状态 与 (1.10) 同步,从调用到 共享状态的等待函数。
在不陷入标准语言的泥潭的情况下,这里的与关系同步意味着在线程设置结果中设置存储结果的调用之前排序的所有内容都发生在wait()
调用之后排序的所有内容之前。
是的,future::wait() 与使未来有效(例如返回异步或设置承诺)同步,因此您正在做的事情是安全的,据我所知,从代码的那部分可以看出。
但是,我发现您使用共享指针是有问题的:将共享指针提供给另一个线程意味着授予该线程(共享)所有权,但是调用 std::move 对shared_ptr的内容几乎与手动调用 delete 一样糟糕。
相关文章:
- 二叉排序树无法编译
- 仅使用绝对值对数组进行排序,并在C++中显示实际值
- C++选择排序算法中的逻辑错误
- 使用C++程序合并排序没有得到正确的输出
- 计算排序向量的向量中唯一值的计数
- 排序算法c++
- 使用2个键的cpp-stl::优先级队列排序不正确
- 将结构向量排序为子组
- 在c++中尝试对对象数组进行排序时,出现std:bad_alloc错误
- 数组将排序排序为降序而不是升序
- 如何按姓氏排序并打印新数组
- 将一个数组的每个元素乘以另一个数组的每个元素,并对新的非常大的数组进行排序
- 合并排序 - 返回新数组,而不是将合并的数组复制到输入数组
- 如何对骰子进行排序并创建每个数组中具有相等骰子的新数组,Yahtzee,C++
- 与排序相关的算法(将每个项目替换为排序排序中的索引)
- 如何将未排序数组的排序索引放入新数组中
- "std::"具有排序/排序、存在测试和头/尾访问的数据结构?
- 创建没有重复项的新排序向量
- 使用快速排序排序不会给出排序的数组
- 读取文本行,对它们进行排序并将它们写入新的文本文件