Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/130.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_C++14_Move_Unique Ptr - Fatal编程技术网

C++ 如何检索指向在单独线程上运行的函数的移动指针?

C++ 如何检索指向在单独线程上运行的函数的移动指针?,c++,multithreading,c++14,move,unique-ptr,C++,Multithreading,C++14,Move,Unique Ptr,当函数在单独的线程上运行时,如何检索已移动到函数中的std::unique_ptr指针 考虑以下示例: using IntPtr = std::unique_ptr<int>; IntPtr&& update(IntPtr &&fp_) { *fp_ = 23; return std::move(fp_); } int main() { IntPtr foo_ptr = std::make_unique<int>

当函数在单独的线程上运行时,如何检索已移动到函数中的
std::unique_ptr
指针

考虑以下示例:

using IntPtr = std::unique_ptr<int>;

IntPtr&& update(IntPtr &&fp_)
{
    *fp_ = 23;
    return std::move(fp_);
}

int main()
{
    IntPtr foo_ptr = std::make_unique<int>(0);
    foo_ptr = update(std::move(foo_ptr));
    std::cout<< "data: " << *foo_ptr <<std::endl;
}
在线代码示例:

您不需要

您将内存的所有权授予了另一个线程。该线程现在拥有该内存,并将在其终止时将其删除。它在加入后不存在,并且您从未将指针移回主线程

如果希望一个线程为另一个线程填充一些数据,那么要么需要使用共享所有权,要么生成线程根本不应该拥有内存(即:传递一个原始指针)

或者只需使用
打包的任务
,您根本不需要(直接)分配内存:

int update(int value)
{
    return 23;
}

int main()
{
    int value = 0;
    std::packaged_task<int(int)> task(update);
    auto future_int = task.get_future();

    std::thread foo_thread(std::move(task), value);
    foo_thread.join();
    std::cout<< "data: " << future_int.get() <<std::endl;
}
int更新(int值)
{
返回23;
}
int main()
{
int值=0;
std::打包任务(更新);
auto future_int=task.get_future();
std::thread foo_thread(std::move(task),value);
foo_thread.join();
std::cout你没有

您将内存的所有权授予了另一个线程。该线程现在拥有该内存,并将在其终止时删除该内存。它在加入后不存在,并且您从未将指针移回主线程

如果希望一个线程为另一个线程填充一些数据,那么要么需要使用共享所有权,要么生成线程根本不应该拥有内存(即:传递一个原始指针)

或者只需使用
打包的任务
,您根本不需要(直接)分配内存:

int update(int value)
{
    return 23;
}

int main()
{
    int value = 0;
    std::packaged_task<int(int)> task(update);
    auto future_int = task.get_future();

    std::thread foo_thread(std::move(task), value);
    foo_thread.join();
    std::cout<< "data: " << future_int.get() <<std::endl;
}
int更新(int值)
{
返回23;
}
int main()
{
int值=0;
std::打包任务(更新);
auto future_int=task.get_future();
std::thread foo_thread(std::move(task),value);
foo_thread.join();

std::cout最简单的方法是只使用一个包装函数,将结果写回
foo_ptr

std::thread foo_thread([&foo_ptr]() {
    foo_ptr = update(std::move(foo_ptr));
});

foo_thread.join();
std::cout<< "data: " << *foo_ptr <<std::endl;

最简单的方法是只使用包装器函数将结果写回
foo\u ptr

std::thread foo_thread([&foo_ptr]() {
    foo_ptr = update(std::move(foo_ptr));
});

foo_thread.join();
std::cout<< "data: " << *foo_ptr <<std::endl;

我想,
join()
告诉主线程等待另一个线程完成。然后它会清除与该线程相关的内存。但我没有意识到你不会得到你的值!在这种情况下,我可以使用
std::ref
取消对指针的引用,并通过引用函数将其底层数据传递给该函数。这样行吗?@ConstantinosGly否:“我以为join()会告诉主线程等待另一个线程完成。”它会这样做。“完成”意味着线程结束,包括销毁线程创建的任何对象。例如,您给它的
unique_ptr
参数。但为什么不使用打包任务并停止分配内存?Nicolas这个问题基本上是问如何从线程返回对象。您的解决方案似乎表明至少这是不可能的,但事实并非如此。@user253751:
promise/future
是从线程返回对象的标准方式。线程函数的返回值被丢弃。是的,您可以使用输出参数或其他类似技术,但是
打包的_任务
是最好的方法。我认为
join()
告诉主线程等待另一个线程完成。然后它会清除与该线程相关的内存。但我没有意识到你不会得到你的值!在这种情况下,我可以使用
std::ref
取消对指针的引用,并通过引用函数将其底层数据传递给该函数。这样行吗?@ConstantinosGly否:“我以为join()会告诉主线程等待另一个线程完成。”它会这样做。“完成”意味着线程结束,包括销毁线程创建的任何对象。例如,您给它的
unique_ptr
参数。但为什么不使用打包任务并停止分配内存?Nicolas这个问题基本上是问如何从线程返回对象。您的解决方案似乎表明至少这是不可能的,但事实并非如此。@user253751:
promise/future
是从线程返回对象的标准方式。线程函数的返回值被丢弃。是的,您可以使用输出参数或其他类似技术,但是
打包的_任务
是最好的方法。谢谢!因为我正在移动pt因此它是一个nullptr,如果在
join()之前由主线程访问它,怎么会有争用条件呢
?内存已移动到函数
fp\uu
。如果主线程在移动后访问
foo\u ptr
,则它的格式不正确,希望编译器能在运行时之前捕获它。@ConstantinosGlynos争用条件是访问智能指针对象
foo\u ptr
,而不是在运行的内存上它指的是。在第一个示例中,线程正在对该智能指针对象进行更改(尽管其值为
nullptr
,但该对象在主线程堆栈上仍处于活动状态)第二个例子没有这个问题,因为它不处理对象,而是移动为线程构造一个新的智能指针。啊,我明白了。谢谢你的解释。对不起,我对多线程还是很陌生。@ConstantinosGlynos不用担心。我仍然记得头当我第一次用线程弄湿双脚时,它会让我感到疼痛,所以请放心,一开始对此感到困惑并不罕见。谢谢!因为我正在移动ptr,因此它是一个空ptr,如果在
join()之前由主线程访问它,为什么会出现争用条件
?内存已移动到函数
fp\uu
。如果主线程在移动后访问
foo\u ptr
,则它的格式不正确,希望编译器能在运行前捕获它。@ConstantinosGly