标签:
本系列文章主要介绍C++11中多线程的使用方法,主要参考书籍为《C++Concurrency IN Action》。
为了保证多线程访问数据的安全性,一种通常的做法是对需要保护的数据上锁,使用mutex保证互斥访问。可以使用的做法是调用lock()和unlock()函数,但是我们更加推荐使用模板类std::lock_guard,在该类的构造函数中完成lock(),而在析构函数中完成unlock()操作。这一技巧和上一章对join()函数的使用是一致的。
简单介绍后我们来看一个可能引起mutex使用错误的例子。
#include <iostream> #include <thread> #include <mutex> class some_data { public: int a; std::string b; void do_someting(){ a--; std::cout << "Break the protected." << endl; std::cout << "a:" << a << endl; }; }; class data_wrapper { private: some_data data; std::mutex m; public: template<typename Function> void process_data(Function func) { std::lock_guard<std::mutex> l(m); func(data); // 1、将受保护的数据传递给func函数 [8/28/2015 pan] } void printData(){ cout << "cuttent data:" << data.a << endl; } };
some_data* unprotected=NULL; void malicious_function(some_data& protected_data) { unprotected = &protected_data; for (int i = 0; i < 100; i++){ unprotected->a++; cout << "a should in protected:" << unprotected->a << endl; } } data_wrapper x; void wrap() { while (true) { if (unprotected != NULL){ unprotected->do_someting();<span style="white-space:pre"> </span>// 4、“未经授权”的访问保护对象 } } } void main() { thread t(wrap);<span style="white-space:pre"> </span>// 2、开启一个新线程测试 x.process_data(malicious_function); // 3、传递一个恶意函数 [8/28/2015 pan] t.join(); x.printData(); }
程序分析:
在main()函数中我们首先开启了一个新的线程去执行wrap()函数,函数在uprotected指针不为空时尝试去访问受保护的对象。
x.process_data()函数对保护数据上锁,但是把data对象的引用传递给了不受控制的恶意函数malicious_function()。如果互斥对象mutex能正常发挥作用,线程t对数据的访问会被挂起,我们应该能顺利执行完100次遍历之后再将控制权传递给线程t。线程t中函数do_someting()用来测试数据的保护性是否被破坏。
实际执行情况是do_someting()与malicious_function()中for循环交替执行,表明数据为能受到保护。
版权声明:本文为博主原创文章,未经博主允许不得转载。
标签:
原文地址:http://blog.csdn.net/panan160/article/details/48048971