是通过const引用传递shared_pointer的线程吗?

时间:2016-05-10 12:52:52

标签: c++ multithreading c++11 thread-safety smart-pointers

我经常读过我应该通过const引用将一个shared_ptr传递给一个函数,因为它的速度更快。当我考虑它时,我不确定这是否是一个非常好的建议,因为我不确定这是否是线程。任何人都可以告诉我这是不是通过const ref传递的线程?

4 个答案:

答案 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的引用则无关紧要。