我经常读过我应该通过const引用将一个shared_ptr传递给一个函数,因为它的速度更快。当我考虑它时,我不确定这是否是一个非常好的建议,因为我不确定这是否是线程。任何人都可以告诉我这是不是通过const ref传递的线程?
答案 0 :(得分:1)
使用&
,您可以获得对象本身。
你没有增加引用计数,你只是将它自己传递给对象。人们建议通过const&
的原因是为了避免线程安全地增加引用计数的成本。作为const&
传递的成本与复制int或指针的成本相同,并且由于const&
的构造函数被标记为{shared_ptr
,因此explicit
不会绑定任何临时对象。 1}}。
因为你总是至少有一个对象的引用(引用从被调用函数绑定的对象),所以当你使用本地引用时,不必担心对象可能会被破坏。
答案 1 :(得分:1)
您应该更喜欢通过const&
来避免任何类副本的开销。例如,这对std::string
等内容尤为重要。
如果将shared_ptr
传递给const&
,则开销主要是incrementing and decrementing of the reference count,因为它是原子的。
<强> BUT!创建具有const& shared_ptr
的线程时有一个问题:引用计数将递增。因为它是递增的,所以几乎就像你按值传递它一样。实际上,您将by-value传递给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
是线程安全的完美候选者,但它不会保护你免受竞争条件和死锁的侵害。
答案 2 :(得分:0)
通过const引用传递是线程无关的。请看以下简单代码:
let sslOptions = {
key: fs.readFileSync('/etc/apache2/ssl/apache.key'),
cert: fs.readFileSync('/etc/apache2/ssl/apache.crt')
};
let server = require('https').createServer(sslOptions, app.callback())
在void foo(const std::shared_ptr<int>& x) {
sleep(100000);
}
void bar() {
//...
std::shared_ptr y = ...;
foo(y);
}
返回之前, y
将会出现在栏中,从而确保foo
仍然有效。如果shared_ptr
要创建另一个帖子并将foo()
传递给它,则必须复制它 - 这会增加引用计数器。
答案 3 :(得分:0)
通过引用传递始终是线程安全的,无论传递什么对象。如果它是对const的引用则无关紧要。