考虑下面的示例,我在specialNumber中创建局部变量main(),并通过引用新线程以及另一个函数传递它(请忽略缺少锁/互斥锁):
#include <iostream>
#include <thread>
void threadRun(int& number) {
while(true) {
std::this_thread::sleep_for(std::chrono::seconds(2));
std::cout << number << std::endl;
number += 1;
}
}
int main() {
int specialNumber = 5;
std::thread newThread(threadRun, std::ref(specialNumber));
otherFunction(specialNumber);
newThread.join();
}
void otherFunction(int& number) {
// does something with number
}我知道,通常应该避免传递对局部变量的引用,因为一旦函数终止,变量将超出作用域,引用将无效。
但是,由于变量是main()的本地变量,而且在整个程序结束之前该函数不会终止,所以这种做法有什么问题吗?
我的具体用例是在这里存储一个小对象(主要由指向堆对象的指针和助手函数组成),它将被多个线程和/或函数使用,并传递对它的引用。我知道另一种方法是使用诸如shared_ptr这样的智能指针将其存储在堆中,但以这种方式存储如此小的对象对我来说似乎效率很低。
如果我的术语不正确,我很抱歉,我对C++非常陌生。请纠正我!
发布于 2020-03-21 19:18:52
你的假设
我知道,通常应该避免传递对局部变量的引用。
似乎毫无根据。
传递对函数的引用没有错。但是,引用对象的函数不应该拥有该对象的所有权。函数不应假设引用的对象在退出后继续存在。
这与返回局部变量的引用不同,局部变量总是错误的。
我认为传递对线程的引用没有问题(忽略了同步),这通常比使用全局变量更可取。
只有当函数应该具有(共享)对象的所有权时,才需要智能指针(如std::shared_ptr ),例如,如果threadRun希望在对象退出后保留对对象的引用/指针。
发布于 2020-03-21 19:45:15
只要main线程处于活动状态,您就不会看到问题发生,因为specialNumber的生命周期是由它控制的。
但是,我想详细说明std::ref()的使用。std::ref()的一个用途就是您正在编码的场景。
当您使用std::ref()时,实际上是返回一个可以复制的std::reference_wrapper。引用包装可以存储在容器中,而普通引用不能。
通过引用将对象传递给线程的构造函数是引用包装器有用和std::ref()返回引用包装器的方法之一。
如果您传递了一个简单的引用,您将看到不同的行为。
阅读更多关于科技促进发展:参考文献()和包装器的信息
这个线程包装有用吗?也很有用。
https://stackoverflow.com/questions/60792100
复制相似问题