Replies: 3 comments
-
首先, 书上原来的想法是:
但是很可惜,shared_ptr::unique() 在 C++17 里被废弃了,所以书上的做法可能在 C++20 就失效了。其实我不是完全赞同 shared_ptr::unique() 被废除的理由,因为本来就应该用 mutex 保护共享的 shared_ptr,然后只要在临界区里检查 unique() 并 copy/reset,这样就没有 race condition 了。 你说的用 Deleter 的办法我没有仔细想过,感觉或许需要针对某个具体的 Foo 定义一个 |
Beta Was this translation helpful? Give feedback.
-
多谢! 我的做法是在构造 shared_ptr 的时候传递 Deleter。就像你说的,这只能针对特定的 class。在这个 Deleter 的 lambda 里往 析构线程 post 一个 task, 这个 task 就是显示的调用析构函数。如下,其中 loop 是一个析构线程,可以是 muduo 里的 loop shared_ptr<Foo> Foo = shared_ptr<Foo>(new Foo(), [](Foo * foo) {
loop->post([foo](){
foo->~Foo();
});
}); 测试下来可行,可能有些边界条件需要注意一下。 |
Beta Was this translation helpful? Give feedback.
-
业务线程一般不需要不断检查,它只需要在处理完请求之后判断一下,比如在假设的 SendResponse/FinishRequest/CloseConnection 之类的函数里检查一下 unique()。 BlockingQueue 是线程安全的,它内部有锁,不需要外部加锁同步。 你的代码没有 |
Beta Was this translation helpful? Give feedback.
-
在这里问这个与
muduo
无关的问题可能不太合适。但是也没有找到其它的地方。我在这个书《Linux多线程服务端编程:使用muduo C++网络库》上看到
现在我就碰到了类似这样的问题,当 shared_ptr 析构线程不一定,当发生在比较重要的线程时,会使关键线程耗时过大。现在想根据上面的建议移到单独的线程来做析构,但不太清楚具体做法。我现在的想法是 在 shared_ptr 构造的时候传入一个
Deleter
,在Deleter
里往析构线程 异步 post 一个 task 来调用析构函数。想请教一下,这样是否合理,会不会也有同步的问题。另外,能不能大致说一下上面书上提到 “通过一个BlockingQueue<shared_ptr>把对象的析构都转移到那个专用线程” 的具体做法?
Beta Was this translation helpful? Give feedback.
All reactions