• std::get<C++11多线程库~线程间共享数据>(10):使用互斥量保护共享数据(2)


     1 #ifndef USE_CODE_PROTECTED_DATA_H
     2 #define USE_CODE_PROTECTED_DATA_H
     3 
     4 /*
     5  * 话题1:使用互斥量保护共享数据
     6  *
     7  * 接下来学习第二个小话题:用代码来保护共享数据
     8  *
     9  *      从第一个小话题可以看到,std::mutex即便可以让线程同步的访问共享数据,设计不好时,同样会出现数据得不到保护的情况。
    10  * 检查指针或引用很容易,只要没有成员函数通过返回值或者输出参数的形式,向其调用者返回指向受保护数据的指针或引用,数据就是安全的。
    11  *
    12  *      如果你还想深究,就没这么简单了。
    13  * 确保成员函数不会传出指针或引用的同时,检查成员函数是否通过指针或引用的方式来调用也是很重要的。
    14  * 函数可能会把共享数据的指针或者引用,存放在没有互斥量保护的区域内,这样就很危险。
    15  * 更危险的是:将保护数据作为一个运行时参数,如同下面清单中所示那样。
    16 */
    17 
    18 /*
    19  *      先来看一下,上面描述的共享数据失去保护的情况。
    20 */
    21 
    22 #include <string>
    23 #include <mutex>
    24 class data{
    25     std::string s;
    26 public:
    27     data(std::string s){
    28         this->s = s;
    29     }
    30 
    31     void do_data_modify(std::string s){
    32         this->s = s;
    33     }
    34 };
    35 
    36 class data_Wrapper{
    37     data m_data;
    38     std::mutex m_mutex;
    39 
    40 public:
    41     data_Wrapper(data d):m_data(d){}
    42     template<typename FuncPtr>
    43     void process_data(FuncPtr func){
    44         std::lock_guard<std::mutex> lk(m_mutex);
    45         func(&m_data);
    46     }
    47 };
    48 
    49 /*
    50  *      可以看出啊, 虽然 std::mutex 可以保护共享数据,并能保证多线程可以同步的安全的访问共享数据,
    51  * 但是,完全可能发生,由于代码设计的不合理, 把本该受到保护的共享数据,以指针或引用的形式交给了不受保护的区域。
    52  * 在不受保护的区域内对共享数据进行修改,这种情况在多线程环境中终将是会发生车祸的。
    53  *
    54  *      虽然这是在使用互斥量保护共享数据时常犯的错误,但绝不仅仅是一个潜在的陷阱而已。
    55  * 下一节中,你将会看到,即便是使用了互斥量对数据进行了保护,条件竞争依旧可能存在。
    56  *
    57  *      如何解决呢?
    58 */
    59 
    60 
    61 /*
    62  * 第二个小话题:用代码来保护共享数据, 使用 std::mutex 也会出现共享数据失去保护的情况。
    63 */
    64 
    65 #include <QCoreApplication>
    66 #include "Use_code_protected_data.h"
    67 data * non_mutex_protected_data = nullptr;
    68 void malicious_func(data *ptrData){
    69     non_mutex_protected_data = ptrData;
    70 }
    71 
    72 int main(int argc, char *argv[])
    73 {
    74     QCoreApplication a(argc, argv);
    75 
    76     data d("healthy data");
    77     data_Wrapper dataWrapper(d);
    78     dataWrapper.process_data(malicious_func);
    79     non_mutex_protected_data->do_data_modify("magic data");  //共享数据在毫无保护的情况下发生了修改。
    80 
    81     return a.exec();
    82 }
    83 
    84 
    85 class Use_code_protected_data
    86 {
    87 public:
    88     Use_code_protected_data();
    89 };
    90 
    91 #endif // USE_CODE_PROTECTED_DATA_H
  • 相关阅读:
    如何使用sendEmail发送邮件
    Linux curl命令详解
    linux比较两个文件是否一样(linux命令md5sum使用方法)
    strace命令用法详解
    strace用法说明
    ORA-12154 TNS无法解析指定的连接标识符
    VNC远程连接阿里云Linux服务器 图形界面
    pycharm配置Git 代码管理
    FireFox浏览器-xpath快速定位插件:Xpath Checker
    odoo 前端模板引擎 Qweb
  • 原文地址:https://www.cnblogs.com/azbane/p/15477540.html
Copyright © 2020-2023  润新知