Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 访问指针的元组和互斥体的元组是否线程安全_C++_Multithreading_Concurrency_Tuples_Stdtuple - Fatal编程技术网

C++ 访问指针的元组和互斥体的元组是否线程安全

C++ 访问指针的元组和互斥体的元组是否线程安全,c++,multithreading,concurrency,tuples,stdtuple,C++,Multithreading,Concurrency,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; 使用Tuple1=std::tuple; 使用Tuple2=st

给定
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;
使用Tuple1=std::tuple;
使用Tuple2=std::tuple;
std::tuple;
以及功能,

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)
}
void baz()
{
自动tup=std::get(tuple);
std::lock_guard lk(*std::get(tup));
//使用std::get(tup)和std::get(tup)执行某些操作
}
根据关于的问题,访问std::tuple本身并不是线程安全的,但是在示例代码中呢?是否可能发生未定义/奇怪的事情


这是假设
FooN
BarN
只有在锁打开后才能访问。

引用您链接的问题的完美答案:

但是,如果参数是const,那么get将不会被视为引发与要get的其他const调用的数据竞争

这基本上就是你的答案
const
元组上进行每个
get
调用(在任何未完全受互斥保护的元组上),您就安全了。

这意味着您发布的代码不安全。这样修改:

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)
}
void baz()
{
//vvvv在这里是明确的
auto const&tup=std::get(static_cast(tuple));
std::lock_guard lk(*std::get(tup));
//取消对std::get(tup)和std::get(tup)的引用,
//随意使用指向对象的指针,而不是其他
//不正常,因为它可能会干扰另一个线程的tup初始化调用
//auto non_const_tup=std::get(tuple)
}
目前我看到的唯一解决方案是使用元组,如:

std::tuple<
    std::shared_pointer<std::mutex>,
    std::unique_pointer<std::tuple<Foo1*, Bar1*>>
    // Mutex and pointer to tuple for Foo2 and Bar2
    >
std::tuple<
std::共享_指针,
std::唯一的_指针
//Foo2和Bar2的互斥量和指向元组的指针
>

所需的
const
将粘贴到所有对象(指针目标除外)。

std::get不会修改
元组的状态,我不能给您一个保证,但我非常确定它会像直接访问底层对象一样工作,这意味着如果底层对象是线程安全的,那么操作将是安全的(实际上)线程安全。如果我理解正确,
tup
中的指针无法修改,为了修改它们,我必须在锁定后重新获取它们的元组?例如
auto tupMutable=std::get(tuple)
。不。您仍然可以同时访问
元组
。我将添加一个解决方案。我想到的解决方案是不正确的。我猜您不希望指向
元组成员的指针?基本上,函数体应该能够修改子元组的指针值。