? c++ ? ? linux ? ? 多线程 ?    发布于 2018-11-07   634人围观   0条评论

前言

最近在读陈硕的moduo网络库的书,记录总结一些东西。

在c++多线程编程中,线程间可能会使用跨线程对象,那么对象在什么时候销毁便成了一个让人头疼的问题,因为一个线程在使用这个对象时,另外一个线程可能正在析构这个对象。该章内容就是为我们解读,如何正确的处理跨线程对象的生命周期,以避免内存泄露、空悬指针或者使得程序处于不确定状态等问题。

线程安全

什么是线程安全?这里给出书中的定义:

一个线程安全的class应当满足以下三个条件:

  • 多个线程同时访问时,能够表现出正确的行为
  • 无论操作系统如何调度这些线程,无论这些线程的执行顺序如何交织
  • 调用段代码无须额外的同步或者其他协调动作

依据这个定义,c++标准库中大多数class都不是线程安全的,包括std::string、std::vector、std::map等,因为这些class通常需要在外部加锁才能供多个线程同时访问

个人的理解就是,一个线程安全的类,即使不用在外部加锁,也可以在多个线程中同时访问,想想,实现这样的类,就很难,这也是为什么多线程编程是我一直想去积累一些东西的原因,这是座山,而我必须得翻过。

多线程中的析构与智能指针

由于在多线程环境中,一个对象可以同时被多个线程访问,这导致析构该对象的时机变得模糊不清。很有可能该对象在一个线程中被访问,而同时在另外一个线程中被析构,这些都会造成程序处于未知的状态。那么我们是否可以加锁来保证析构时,其他线程不会访问呢?遗憾的是,析构时锁作为对象的一部分也会被析构,这样就无法对临界区进行保护。

实际上,我们在多线程编程使用原始指针时,不得不思考一个问题,那就是什么时候对象的析构才是安全的?只有其他线程都访问不到该对象的时候才是安全的。自然而然,我们可以想到使用智能指针来引入一层间接性的引用计数。对于跨线程对象而言,最好使用标准库中的智能指针进行处理,智能指针的核心是引用计数。智能指针的思想符合用对象管理资源的思路,实际上,现代c++程序一般不会出现内存泄露的情况,除非特别情况,一般都会使用容器或者智能指针来管理资源。

用智能指针代替原始指针的一大好处是原始指针无法判断所指内存上的对象是否销毁,而只要有智能指针引用计数不为0,所指涉内存上的对象便不会被销毁。

观察者模式与智能指针

 

#include <algorithm>
#include <vector>
#include <stdio.h>

cl
查看更多