Sam*_*ami 6 c++ multithreading shared-ptr
std::shared_ptr<Dog> pd;
void F() {
pd = std::make_shared<Dog>("Smokey");
}
int main() {
std::thread t1(F);
std::thread t2(F);
t1.join();
t2.join();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
std::shared_ptr<Dog> pd(new Dog("Gunner"));
void F() {
std::shared_ptr<Dog> localCopy = pd;
}
int main() {
std::thread t1(F);
std::thread t2(F);
t1.join();
t2.join();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
在 C++ 中,我知道 std::shared_ptr 对于读取和复制来说是线程安全的。但我对何时需要使用互斥体来同步线程有点困惑。我有两个代码片段。在第一个中,std::shared_ptr 被多个线程修改。在第二个线程中,每个线程仅读取和复制共享指针。在这两种情况下我都需要互斥体,还是只在第一种情况下需要互斥体?为什么或者为什么不?”
如果您仔细识别所涉及的所有移动部分,就更容易理解这一点:
一个引用计数对象,这是一个对象,在某个地方,这是你的Dog
引用计数器本身,它跟踪对引用计数对象的引用数量
使用引用计数器的共享指针本身
这些都是离散的实体,需要单独考虑和评估。
根据经验,在 C++ 中,如果从多个执行线程访问一个对象,并且至少一个执行线程以某种方式“修改”它,则执行线程必须相对于该对象“同步”;除非该对象是“线程安全的”。“同步”是什么意思?嗯,它不仅仅意味着某个地方的互斥锁;它还意味着一个互斥体。但对于这个实际示例来说,这就是它的含义:您需要在某个地方的某个互斥锁上持有锁的同时访问该对象。
数据点:引用计数器是线程安全的。智能指针,又名std::shared_ptr不是。
pd = std::make_shared<Dog>("Smokey");
Run Code Online (Sandbox Code Playgroud)
这会修改多个执行线程中的共享指针pd。这需要同步,这不是线程安全的。你需要一个互斥体。
std::shared_ptr<Dog> localCopy = pd;
Run Code Online (Sandbox Code Playgroud)
这会复制 的副本pd,但不会对其进行修改。作为复制(和销毁)参考计数器的一部分,这也会影响参考计数器。引用计数器是线程安全的。共享指针未被修改,仅被访问。这是线程安全的。