当我在这里阅读cppreference中的文档时,https://en.cppreference.com/W/cpp/memory/shared_ptr#示例
我想知道打印出来的第一个lp.use_count()
可能的值是什么?我用“在输出内容中。
#include <iostream> #include <memory> #include <thread> #include <chrono> #include <mutex> struct Base { Base() { std::cout << " Base::Base()\n"; } // Note: non-virtual destructor is OK here ~Base() { std::cout << " Base::~Base()\n"; } }; struct Derived: public Base { Derived() { std::cout << " Derived::Derived()\n"; } ~Derived() { std::cout << " Derived::~Derived()\n"; } }; void thr(std::shared_ptr<Base> p) { std::this_thread::sleep_for(std::chrono::seconds(1)); std::shared_ptr<Base> lp = p; // thread-safe, even though the // shared use_count is incremented { static std::mutex io_mutex; std::lock_guard<std::mutex> lk(io_mutex); std::cout << "local pointer in a thread:\n" << " lp.get() = " << lp.get() << ", lp.use_count() = " << lp.use_count() << '\n'; } } int main() { std::shared_ptr<Base> p = std::make_shared<Derived>(); std::cout << "Created a shared Derived (as a pointer to Base)\n" << " p.get() = " << p.get() << ", p.use_count() = " << p.use_count() << '\n'; std::thread t1(thr, p), t2(thr, p), t3(thr, p); p.reset(); // release ownership from main std::cout << "Shared ownership between 3 threads and released\n" << "ownership from main:\n" << " p.get() = " << p.get() << ", p.use_count() = " << p.use_count() << '\n'; t1.join(); t2.join(); t3.join(); std::cout << "All threads completed, the last one deleted Derived\n"; }
可能的输出:
Base::Base()
Derived::Derived()
Created a shared Derived (as a pointer to Base)
p.get() = 0x2299b30, p.use_count() = 1
Shared ownership between 3 threads and released
ownership from main:
p.get() = 0, p.use_count() = 0
local pointer in a thread:
lp.get() = 0x2299b30, lp.use_count() = 5 <<<<<<<< HERE <<<<<<
local pointer in a thread:
lp.get() = 0x2299b30, lp.use_count() = 3
local pointer in a thread:
lp.get() = 0x2299b30, lp.use_count() = 2
Derived::~Derived()
Base::~Base()
All threads completed, the last one deleted Derived
@user2452809的回答令人非常赞赏,它指出了use_count()
的一个重要特性。
假设use_count()
将返回一个精确的计数,那么答案是什么?
反正我也不会依赖这个值。
在多线程环境中,use_count返回的值是近似的(典型的实现使用memory_order_relaved加载)
有关详细信息,请查看参考:https://en.cppreference.com/W/cpp/memory/shared_ptr/use_count
我认为它可能是{4,5,6}的一个值。我说的对吗?
问:为什么大于3?
答:打印时,至少调用一个thr
函数。包括主函数中的引用。use_count应为3。但是当一个线程休眠了一秒而另两个线程还没有构造时,就不可能了。另一方面,如果有两个线程完成,最后一个线程的use_count将为3。但由于打印范围中的线程互斥,它不会是第一行。
问:为什么少于7?
答:因为在子线程睡眠期间,主线程将运行p.reset()
。一秒钟对CPU来说是相当长的时间。