微软说,即使有多个副本共享同一对象,也应使用此页面上的“线程安全”shared_ptr
。
那么这是否意味着以下两个条件都可以接受?我都尝试过,它们似乎工作正常。
编辑:实际的业务目标是从长时间运行的线程到主线程获取字符串更新。我想应该使用,shared_ptr
因为string
它不是线程安全的。不要老实地在乎所有权。
选项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();
EDIT2:显然,这两种方法对于我要实现的目标都是错误的。我需要使用std::mutex
(cppreference)而不是与之混为一谈shared_ptr
。请参阅此答案的下半部分。
通常,线程可能会超出创建它们的作用域。在这种情况下,在线程仍在运行时,可能会破坏通过引用捕获的任何局部变量。如果是这种情况,那么您不应通过引用进行捕获。
此外,在一个线程中修改共享指针对象并在不同步的情况下访问另一个线程会导致未定义的行为。如果这是您要执行的操作,则应使用std::atomic_load
/atomic_store
函数访问该指针,或仅将指针复制到每个线程中。请注意,您可以通过副本捕获:
auto f = [status]() {
此外,共享指针不提供额外的线程安全性来访问所指向的对象,除了保持所有权有效并确保将其删除一次即可。如果指定的类型不是原子类型,则在一个线程中对其进行修改并在不同步的情况下访问另一个线程将导致未定义的行为。如果这是您要执行的操作,则需要使用互斥锁或类似方法。或将指向对象本身复制到每个线程中。
关于已编辑的问题:您的示例适用于后一种情况。他们两个都有不确定的行为。您需要同步。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句