本系列为《你会不会处理多线程中的XXXX》 。 看上面那张图,是不是能联想到多线程? 就那七个张伟,他们有一个共用属性,钱包里的钱。这天,张伟A在吃喝的时候,发现钱给没了,原因是张伟B拿去捐款了,那就很尴尬了。为了避免这种情况,怎么办?他们商量了一下,给钱包上个锁,是吧,谁要用谁上锁。上了锁谁都别用,用完再解锁,大家再用。 本篇的主角,是对象与线程安全, 参考博客:可重入函数对于线程安全的意义 对象构造要做到线程安全,就一点要求:不要暴露自己,即不要泄露this指针。 对于第一点,如果非要回调函数才能构造,那就换二段式构造,先构造,在调用回调函数。 之所以要这样设计(把this传给子类那另当别论),就是为了防止构造过程被打断,构造出一个半成品。 对象析构,在多线程里,由于竞态的存在,变得扑朔迷离。 那这就有一个很尴尬的情况了: 那怎么办? 一个动态创建的对象,是否还有效光看指针是看不出来的指针就是指向了一块内存而已,这块内存上的对象如果已经被销毁,那就根本不能访问。 shared_ptr是引用计数型智能指针,被纳入C11标准库。shared_ptr是一个类模板,它只有一个参数,使用起来很方便。 shared_str是强引用,只要有一个指向x对象的shared_ptr存在,该对象及不会被析构。 讲这么多不如来个例子实在: C++里面可能出现的内存问题大致有这么几个方面 对应解决:
前言
本系列参考资料:陈硕的《Linux服务端多线程编程》、还有我的经验。
适用人群:要有一定的C++基础、要会百度、要有一定的Linux服务器编程经验。
本文语言比较粗糙,应该不至于引起什么不适,大家都是成年人了。多线程与线程安全
但是呢?今天张伟A在吃饭之前,看了下钱包,钱还够,但是总不能这会儿把钱包锁了吧,吃个饭那么久,别人都不要用了吗?所以他就没锁。就在这档口,张伟C买了个王者荣耀新出的皮肤,完了,我们可怜的张伟A要结账的时候,没钱了,又要刷盘子了。
所以说,这个锁啊,并不能百分百的就保证线程的安全。
像这种情况啊,那怎么办?那就在吃饭结账的时候看一眼有没有钱,没钱那就吃慢点,等着钱包的钱又有了再说。
这是操作系统的资源调度算法,拿来举个例子说线程安全。
对象有什么线程安全的隐患?无非指针悬挂,内存泄漏;又或者多次释放,内存错乱。对象的创建很简单
那就是做到以下几点:不要在构造函数中注册任何回调 不要在构造函数中将this传给跨线程对象 即时在构造函数最后一行也不行
对于第三条,如果这个类是个基类呢?它构造完了并不是真的构造完了,还有子类等着呢。对象的销毁与竞态条件
看个例子:Foo::~Foo(){ //拿锁 //析构 //解锁 } void Foo::update(){ //拿锁 //数据操作 //解锁 } extern Foo *f;//共享资源 A进程操作 delete f; f = NULL; B进程操作 if(f) { f->update(); }
A在执行“析构”的时候,已经拿到了锁,而B通过了 f 的判断,因为那会儿指针还活着,然后被锁卡住了。
接下来会发生什么?不知道,因为对象析构的时候把锁也带走了。。。(锁属于对象,对象析构,锁也跑不了)
别怕,参考博客:智能指针shared_ptr/weak_ptr
weak_ptr是弱引用,它不控制对象的生命周期,但是它知道对象是否还存在。如果对象存在,它可以升级成为shared_ptr。class Observer{ private: std::vector<weak_ptr<Observer>> vwo; //像这样用啊 }
再聊聊C++内存安全
本网页所有视频内容由 imoviebox边看边下-网页视频下载, iurlBox网页地址收藏管理器 下载并得到。
ImovieBox网页视频下载器 下载地址: ImovieBox网页视频下载器-最新版本下载
本文章由: imapbox邮箱云存储,邮箱网盘,ImageBox 图片批量下载器,网页图片批量下载专家,网页图片批量下载器,获取到文章图片,imoviebox网页视频批量下载器,下载视频内容,为您提供.
阅读和此文章类似的: 全球云计算