我经常阅读我应该通过一个函数const引用shared_ptr,因为它更快。当我想到它时,我不确定这是否是一个好的建议,因为我不确定这是否是线程化的。任何人都可以告诉我,如果这将是通过const ref传递的线程吗?它通过const引用传递shared_pointer线程吗?
回答
你应该更喜欢通过const&
来避免任何类的副本的开销。例如,这对于像std::string
这样的东西特别重要。
在通过shared_ptr
const&
的情况下,开销主要是incrementing and decrementing of the reference count,因为它是原子的。
但是!与const& shared_ptr
创建线程时有一个问题:引用计数将递增。既然它增加了,就好像你已经通过价值传递了它。你实际上是通过价值传递到std::thread
ctor,从而增加,然后通过ref传递给函数。
见自己:
// gcc (Ubuntu 4.8.4-2ubuntu1~14.04.1) 4.8.4
void test(const shared_ptr<int>& i)
{
cout << "c = " << i.use_count() << endl;
}
int main(int argc, char** argv)
{
shared_ptr<int> i(new int);
cout << "c = " << i.use_count() << endl;
test(i);
cout << "thread!" << endl;
thread t(test, i);
t.join();
cout << "c = " << i.use_count() << endl;
}
结果之中:
c = 1
c = 1
thread!
c = 2 // <= incremented!
c = 1 // <= thread joined!
shared_ptr
是线程安全的一个完美的候选人,但它不会保护你的比赛条件和死锁。
With a &
you get the object itself。
你没有增加参考数量,你只是通过它自己的对象。人们建议通过const&
的原因是为了避免线程安全增加参考计数的成本。作为const&
传递的代价与复制int或指针的代价相同,并且没有临时对象将被绑定到const&
,因为shared_ptr
的构造函数标记为explicit
。
而且由于您始终至少有一个对象引用(引用与被调用函数绑定的对象),所以不用担心在使用本地引用时对象可能会被破坏。
如果引用绑定的对象超出范围会发生什么?它不会被破坏,因为refcount然后是0.如果这会发生,我会使用内存,如果我使用ref – Exagon
传递一个'const&'与一个普通'&'不同?两者都只是参考,所以不应引用计数更改。 – rozina
@Exagon,它是如何超出范围的?你调用了传递本地'shared_ptr'的函数。它至少不能超出范围,直到你从该函数返回并且直到当前块'shared_ptr'到达结尾。例如'{std :: shared_ptr
传递const引用是线程无关的。看看下面简单的代码:
void foo(const std::shared_ptr<int>& x) {
sleep(100000);
}
void bar() {
//...
std::shared_ptr y = ...;
foo(y);
}
y
想要住在酒吧,直到foo
回报 - 从而确保shared_ptr
仍然有效。如果foo()
要创建另一个线程并将x
传递给它,它将不得不复制它 - 这将增加引用计数器。
通过引用传递总是线程安全的,无论哪个对象被传递。如果它是对const的引用,它是无关紧要的。
- 1. 通过引用传递const值的C++
- 2. 通过const引用传递Qt类
- 3. 通过const引用传递的C++
- 4. 通过引用传递TCL - 线程?
- 5. 通过引用线程传递对象
- 6. 通过值或通过引用const传递std :: chrono :: duration?
- 7. 是否更好地通过引用对非const传递引用进行const传递?
- 8. 通过const引用传递一个对象?
- 9. 通过const引用复制传递C++对象构造函数
- 10. C++通过Const引用并通过Const返回引用
- 11. 通过引用传递与值传递
- 12. 通过引用传递C++
- 13. C++通过引用传递?
- 14. cpp通过引用传递
- 15. PHP通过引用传递?
- 16. Java通过引用传递
- 17. C++通过引用传递
- 18. 通过引用传递流
- 19. JFrame通过引用传递
- 20. 通过引用传递LPCWSTR
- 21. Java通过引用传递
- 22. 通过引用传递整数与线程
- 23. 尝试引用与const成员通过引用传递时删除的函数
- 24. 通过引用传递引用?
- 25. 通过类的const引用
- 26. Java是通过值传递还是通过引用传递?
- 27. 通过引用传递和递归
- 28. 为什么它可以通过const引用传递R值而不是正常引用?
- 29. 通过引用传递通道隐含
- 30. 引用问题传递const对象
'std :: thread'构造函数复制/移动所有参数。 – GeorgeAl
@GeorgeAl Thx,补充说,精度 – BlakBat