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++ 我可以返回std::thread吗_C++_Multithreading - Fatal编程技术网

C++ 我可以返回std::thread吗

C++ 我可以返回std::thread吗,c++,multithreading,C++,Multithreading,从函数返回std::thread安全吗 乙二醇 std::thread getWindowThread(std::函数f){ 标准:螺纹t(f); 返回t; } std::function func=[](){}; std::thread winT=getWindowThread(func); winT.join(); 是的,很安全。该线程将被移动到winT 是的,只要函数的返回值用于初始化或分配给另一个std::thread对象,它是安全的 std::thread的析构函数的唯一先决条件是jo

从函数返回std::thread安全吗

乙二醇

std::thread getWindowThread(std::函数f){
标准:螺纹t(f);
返回t;
}
std::function func=[](){};
std::thread winT=getWindowThread(func);
winT.join();

是的,很安全。该线程将被移动到winT

是的,只要函数的返回值用于初始化或分配给另一个
std::thread
对象,它是安全的

std::thread
的析构函数的唯一先决条件是
joinable()
false

~thread()
效果:如果
joinable()
,则调用
terminate()
。否则,就没有效果

若要成为可接合()
,线程的ID必须不等于初始化ID的值:

bool joinable()const noexcept
返回:
get\uid()
!=<代码>id()

std::thread
的move构造函数和move赋值运算符指定从线程移动的线程的ID将等于初始ID的值,因此将不可
joinable()

thread(thread&&x)无异常
后置条件:
x.get-id()==id()
get-id()
返回开始构造之前的
x.get-id()

thread&operator=(thread&x)无异常

后置条件:
x.get-id()==id()
get-id()
返回赋值前的
x.get-id()
值。

由于
getWindowThread
返回函数局部变量,其返回值将根据返回的对象进行移动构造,而
winT
将根据
getWindowThread
返回的值进行移动构造,因此您的示例是安全的。返回的
线程
对象不再是
可连接的
,可以销毁

但是,如果返回的值不用于初始化或分配给另一个
std::thread
对象,则其析构函数将调用
std::terminate()
,并使程序崩溃。因此,我建议在函数中添加
[[nodiscard]]
属性,以确保编译器在这种危险情况下至少发出警告(如果您可以访问C++17功能,否则会有编译器特定的扩展来启用相同的行为):

[[nodiscard]]std::thread getWindowThread(std::function f){
标准:螺纹t(f);
返回t;
}
看一看。您可以检查
std::thread
copy构造函数(和复制分配)是否已被删除。在C++中,请参阅更多关于<代码>移动构造函数< /> > >

当您从函数返回std::thread时,它返回的对象是move-constructed,并且变量
winT
也将是move-constructed,因为函数返回具有值类别的对象

这应该有效,不会导致任何未定义的行为。您可能会认为,一旦从函数返回
std::thread
,它将被销毁,它的资源必须释放,并且它的线程可能会被销毁

但如前所述,在函数中创建的对象将被移动构造为构造
winT
对象

详细信息: 林克说:

如果*this有一个关联的线程(joinable()==true),则调用std::terminate()

因此,要安全地销毁任何std::thread对象,您需要确保它不可连接。提供了有关这方面的更多信息:

因此,默认构造的线程是不可连接的。已完成代码执行但尚未联接的线程仍被视为活动执行线程,因此可以联接


所以,当winT的move构造函数构造它时,它本身就带有从函数返回的对象。在此之后,函数的临时部分将被销毁,因为它不可连接,所以销毁它是安全的。

是的,代码定义了行为,并按照您的预期工作。你有什么怀疑的理由吗?我有一个关于gmock返回线程的后续问题,例如:std::function lamda=[](){};std::线程和线程(lamda);EXPECT_调用(,getWindowThread()).willrepeated(返回(wThread));由于无法复制线程,因此引发异常。我怎样才能归还模拟文件?@vedikaseth谷歌的文档涵盖了这一点。如果你仍然不知道该做什么,你应该把它作为一个新问题来问。
std::thread getWindowThread(std::function<void()> f){
    std::thread t(f);
    return t;
}

std::function<void()> func = [](){};
std::thread winT = getWindowThread(func);
winT.join();
[[nodiscard]] std::thread getWindowThread(std::function<void()> f) {
    std::thread t(f);
    return t;
}
std::thread winT = getWindowThread(func);