Bab*_*iff 5 c++ concurrency multithreading tuples stdtuple
鉴于std::tuple,
using Tuple1 = std::tuple<Foo1*, Bar1*, std::shared_ptr<std::mutex>>;
using Tuple2 = std::tuple<Foo2*, Bar2*, std::shared_ptr<std::mutex>>;
std::tuple<Tuple1, Tuple2> tuple;
Run Code Online (Sandbox Code Playgroud)
而功能,
void baz()
{
auto tup = std::get<0>(tuple);
std::lock_guard<std::mutex> lk(*std::get<2>(tup));
// Do something with std::get<0>(tup) and std::get<1>(tup)
}
Run Code Online (Sandbox Code Playgroud)
根据这个关于SO的问题,访问a std::tuple本身并不是线程安全的,但是在示例代码的情况下呢?是否有可能发生未定义/奇怪的事情?
这是假设FooN&BarN只能在锁定后访问.
引用您链接的问题的完美答案:
但是,如果参数是 const,则 get 不会被视为引发与其他 const 调用的数据争用。
这基本上就是你的答案。在元组上进行每次get调用(在任何未完全受互斥体保护的const元组上),您都是安全的。
这意味着您发布的代码不安全。像这样修改:
void baz()
{
// vvvv just being explicit here
auto const & tup = std::get<0>(static_cast<decltype(tuple) const &>(tuple));
std::lock_guard<std::mutex> lk(*std::get<2>(tup));
// Dereference std::get<0>(tup) and std::get<1>(tup),
// use the pointed to objects at will, nothing else
// Not ok, because it could interfer with the call in initialisation of tup of another thread
// auto non_const_tup = std::get<0>(tuple)
}
Run Code Online (Sandbox Code Playgroud)
目前我看到的唯一解决方案是使用如下元组:
std::tuple<
std::shared_pointer<std::mutex>,
std::unique_pointer<std::tuple<Foo1*, Bar1*>>
// Mutex and pointer to tuple for Foo2 and Bar2
>
Run Code Online (Sandbox Code Playgroud)
所需的const将坚持一切(除了指针目标)。
| 归档时间: |
|
| 查看次数: |
203 次 |
| 最近记录: |