博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Effective_STL 学习笔记(十二) 对STL线程安全性的期待现实一些
阅读量:6607 次
发布时间:2019-06-24

本文共 2041 字,大约阅读时间需要 6 分钟。

 

  标准C++的世界是相当保守和陈旧的。在这个纯洁的世界,所有可执行文件都是静态链接的。不存在内存映射文件和共享内存。没有窗口系统,没有网络,没有数据库,没有其他进程。在这种情况下,当发现标准没有提到任何关于线程的东西时你不该感到惊讶。你对STL的线程安全有的第一个想法应该是它将因实现而不同。

在STL容器里对多线程支持的黄金规则已经由SGI定义:

  1. 多个读者是安全的。多线程可能同时读取一个容器的内容,这将正确的执行,

   当然,在读取时不能有任何写入者操作这个容器;

  2. 对不同容器的多个写入者是安全的。多线程可以同时写不同的容器。

一个库可能试图以下列方式实现线程安全的容器:

  1. 每次调用容器的成员函数期间都要锁定该容器;

  2. 每个容器返回的迭代器的生存期之内都要锁定该容器;

  3. 在每个容器上调用算法执行期间锁定该容器。

 

上面列举的锁定方法并不能防止下面代码的问题

1   vector
v;2   vector
:: iterator first5( find( v.begin(), v.end(), 5 ) );   // 行13   if( *first5 != v.end() )                          // 行24     *first5 = 0;                                // 行3

  例如,另一个线程在行1完成之后立刻修改 v 中的数据,导致行2、行3不能正常运行

 

为了代码成为线程安全的,v必须从行1到行3保持锁定,手工同步控制

1     vector
v;2 ...3 getMutexFor(v);4 vector
:: iterator first5( find( v.begin(), v.end(), 5 ) );5 if( *first5 != v.end() )            // 这里现在安全了6 *first5 = 0;                 // 这里也是 7 8 releaseMutexFor(v);

 

一个更面向对象的解决方案是创建一个Lock类,在构造函数里获得互斥量并在析构函数里释放它,

这样使 getMutexFor 和 releaseMutexFor的调用不匹配的机会减到最小:

1   template
  // 获取释放容器的互斥量的类的模板核心 2   class Lock 3   { 4   public: 5     Lock(const Containers container) : c(container) 6     { getMuxtexFor(c);   }    // 在构造函数获取互斥量  7     ~Lock() 8     { releaseMuxtexFor(c); }   // 在析构函数里释放它 9   private:10     const Container & c;11   };

 

使用Lock类来获取互斥量:

1     vector
v;2 ...3 {
  // 建立新块4 Lock< vector
> lock(v); // 获取互斥量5 vector
:: iterator first5( find( v.begin(), v.end(), 5 ) );6 if( *first5 != v.end() )           7 *first5 = 0;                 8 9 } // 关闭块,自动释放互斥量

  建立一个里面定义了Lock的新块,当不再需要互斥量时就关闭那个块

 

另外,Lock的方法在有异常的情况下也是文件的。而 getMutexFor 与 releaseMutexFor 之间有异常抛出,将不会释放互斥量。

当涉及到线程安全和STL容器时,可以确定库实现允许在一个容器上的多个读者和不同容器的多写入者。

 

 

 

 

 

 

  

转载于:https://www.cnblogs.com/kidycharon/p/10005813.html

你可能感兴趣的文章
setjmp与longjmp的分析
查看>>
generate ascii table
查看>>
2013吉林通化邀请赛 1005 GCD and LCM
查看>>
高淇java300集JAVA常用类作业
查看>>
<Linux命令行学习 第一节> CentOS在虚拟机的安装
查看>>
无Paper不论文
查看>>
mysql设置字符集CHARACTER SET
查看>>
redis 系列15 数据对象的(类型检查,内存回收,对象共享)和数据库切换
查看>>
log框架集成
查看>>
python命令行下安装redis客户端
查看>>
如何在Oracle中复制表结构和表数据
查看>>
[河南省ACM省赛-第四届] 序号互换 (nyoj 303)
查看>>
3 Oracle 32位客户端安装及arcgis连接
查看>>
[MFC] MFC编译程序,缺少MFC动态链接库的解决
查看>>
Android进阶2之APK方式换肤
查看>>
Sticker.js – 帮助你在网站中加入贴纸效果
查看>>
命名参数
查看>>
windows服务与计划任务
查看>>
重新想象 Windows 8 Store Apps (8) - 控件之 WebView
查看>>
JAVA中的File类
查看>>