gpt4 book ai didi

c++ - 在 C++ 线程中,我应该通过值还是引用传递 shared_ptr?

转载 作者:行者123 更新时间:2023-12-03 17:44:29 24 4
gpt4 key购买 nike

此页面位于 Thread Safety微软说 shared_ptr即使有多个拷贝共享同一个对象,也应该使用它。
那么这是否意味着以下两种情况都可以接受?我已经尝试了两者,它们似乎工作正常。
编辑 :实际的业务目标是从长时间运行的线程到主线程获取字符串更新。我想我应该使用 shared_ptrstring不是线程安全的。不要诚实地关心所有权。
选项 1(传递引用):

auto status = std::make_shared<std::string>();
auto f = [&status]() {
...
*status = "current status";
...
};

std::thread t{f};

while(true) {
std::cout << *status << std::endl;
std::this_thread::sleep_for(1000ms);
if (*status == "completed") break;
}

t.join();
选项 2(制作拷贝):
auto status = std::make_shared<std::string>();
auto f = [](std::shared_ptr<std::string> s) {
...
*s= "current status";
...
};

std::thread t{f, status};

while(true) {
std::cout << *status << std::endl;
std::this_thread::sleep_for(1000ms);
if (*status == "completed") break;
}

t.join();
编辑2:因此,显然这两种方法对于我想要实现的目标都是错误的。我需要使用 std::mutex ( cppreference ) 而不是与 shared_ptr 混在一起.见下半篇 this answer .

最佳答案

通常,线程可能会在创建它们的范围内存活。在这种情况下,任何通过引用捕获的局部变量都可能在线程仍在运行时被销毁。如果是这种情况,则不应通过引用捕获。
此外,在一个线程中修改共享指针对象并在没有同步的情况下访问另一个线程会导致未定义的行为。如果这就是你所做的,那么你应该使用 std::atomic_load 访问指针。/atomic_store函数,或者简单地将指针复制到每个线程中。请注意,您可以通过拷贝捕获:

auto f = [status]() {

此外,共享指针不提供额外的线程安全来访问指向的对象,除了保持所有权处于事件状态并确保它被删除一次。如果指向的类型不是原子的,那么在一个线程中修改它并在没有同步的情况下在另一个线程中访问会导致未定义的行为。如果这就是你正在做的,你需要使用互斥锁或类似的东西。或者将指向的对象本身复制到每个线程中。
关于编辑后的问题:您的示例适用于最后一个案例。他们都有未定义的行为。你需要同步。

关于c++ - 在 C++ 线程中,我应该通过值还是引用传递 shared_ptr?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66454810/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com