chrome源码里weakptr的使用

小宇去读书 2014-04-18 03:33:39
最近在看chrome源码,对weakptr的使用来使task具有撤销特性大致有了一个了解,但是也有一个问题:
weakptr是使用弱引用来使原有引用对象析构时,自身可以通过查询得到引用对象已经失效,一般性使用为:
    
template<class Method, class Params>
class RunnableMethod : public CancelableTask
{
public:
RunnableMethod(const base::WeakPtr<T>& obj,
Method meth, const Params& params)
: obj_(obj), meth_(meth), params_(params)
{
COMPILE_ASSERT((MethodUsesScopedRefptrCorrectly<Method, Params>::value),
badscopedrunnablemethodparams);
}

virtual void Run()
{
if(obj_)
{
DispatchToMethod(obj_.get(), meth_, params_);
}
}
virtual void Cancel()
{
obj_.reset();
}

private:
base::WeakPtr<T> obj_;
Method meth_;
Params params_;

DISALLOW_COPY_AND_ASSIGN(RunnableMethod);
};


为题就是在run函数这里:
virtual void Run()
{
if(obj_) //判断引用对象是否有效,weakptr等一系列函数的功劳
{
DispatchToMethod(obj_.get(), meth_, params_); //有效的话执行函数调用
}
}

有种情况就是run是在另一个线程中执行,执行时得知obj_有效,进入meth_调用,此时obj_对象的拥有线程执行了obj对象的析构,那么此时meth_调用中访问obj的成员变量就会发生不可预知的行为了,这种情况是如何避免的,欢迎大家指教。
...全文
527 5 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
sumos 2014-11-20
  • 打赏
  • 举报
回复
与c++的weak_ptr一样,weak_ptr是线程安全,但是task就不是了, NOTE: This only works when the task is posted to the same thread. 这句话是对的,必须保证你的对象 和 该task在同一线程 或者说保证task执行时对象不会被删除
ri_aje 2014-11-20
  • 打赏
  • 举报
回复
不知道 google 家的 weakptr 具体怎么写的。 标准的 weak_ptr lock 的时候会返回 shared_ptr,从而保证引用计数没有线程问题,不过多线程读写被管理对象仍然需要同步。
misserwell 2014-11-19
  • 打赏
  • 举报
回复
楼主的意思 是 不是 NOTE: This only works when the task is posted to the same thread. 这句话
  • 打赏
  • 举报
回复
应该和std::weak_ptr std::tr1::weak_ptr boost::weak_ptr是类似的,是shared_ptr的补充
小宇去读书 2014-04-18
  • 打赏
  • 举报
回复
官方文档写明了这种方式是non threadsafe的,哎,翻遍了整个baidu都没有看到这个,还是官方的英文文档靠谱。。 base::WeakPtr and Cancellation [NOT THREAD SAFE] You can use a base::WeakPtr and base::WeakPtrFactory (in base/memory/weak_ptr.h) to ensure that any invokes can not outlive the object they are being invoked on, without using reference counting. The base::Bind mechanism has special understanding for base::WeakPtr that will disable the task's execution if the base::WeakPtr has been invalidated. The base::WeakPtrFactory object can be used to generate base::WeakPtr instances that know about the factory object. When the factory is destroyed, all the base::WeakPtr will have their internal "invalidated" flag set, which will make any tasks bound to them to not dispatch. By putting the factory as a member of the object being dispatched to, you can get automatic cancellation. NOTE: This only works when the task is posted to the same thread. Currently there is not a general solution that works for tasks posted to other threads. See the next section about CancelableTaskTracker for an alternative solution. class MyObject { public: MyObject() : weak_factory_(this) {} void DoSomething() { const int kDelayMS = 100; MessageLoop::current()->PostDelayedTask(FROM_HERE, base::Bind(&MyObject::DoSomethingLater, weak_factory_.GetWeakPtr()), kDelayMS); } void DoSomethingLater() { ... } private: base::WeakPtrFactory<MyObject> weak_factory_; };

65,187

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧