C++ 并发编程笔记——线程共享数据
线程共享数据
前言: 设计一个共享栈,可以实现并发访问。
// 定义一个异常结构体
struct empty_stack : std::exception
{
const char* what() const throw() {
return "empty stack";
};
};
template<typename T>
class threadsafe_stack
{
private:
std::stack<T> data;
// 与const相反
mutable std::mutex m;
public:
// 无参构造函数
threadsafe_stack()
: data(std::stack<T>()) {}
// 有参构造函数
threadsafe_stack(const threadsafe_stack& other) {
std::lock_guard<mutex> lock(other.m);
data = other.data;
}
threadsafe_stack& operator=(const threadsafe_stack&) = delete;
void push(T new_value) {
std::lock_guard<std::mutex> lock(m);
data.push(new_value);
}
std::shared_ptr<T> pop() {
std::lock_guard<std::mutex> lock(m);
if (data.empty()) throw empty_stack();
std::shared_ptr<T> const res(std::make_shared<T>(data.top()));
data.pop();
return res;
}
void pop(T& value) {
std::lock_guard<mutex> lock(m);
if (data.empty()) throw empty_stack();
value = data.top();
data.pop();
}
int size() {
std::lock_guard<mutex> lock(m);
return data.size();
}
//const限制表示成员函数中不会修改成员变量值
bool empty() const{
lock_guard<mutex> lock(m);
return data.empty();
}
};
// main 函数
int main() {
//std::stack<int> stack;
threadsafe_stack<int> stack;
thread test1(A, ref(stack));
thread test2(B, ref(stack));
test1.join();
test2.join();
cout << "总共: " << stack.size() << endl;
while (!stack.empty()) {
int temp;
// 引用传递
stack.pop(temp);
//stack.pop();
cout << temp << endl;
}
system("pause");
}
前言: 一种即使加锁,但是数据引用被泄露,也会引起数据不安全的场景。
//#include "OpenCvTest.h"
#include "LeetcodeTest.h"
#include <iostream>
#include "MyHashSet.h"
#include <unordered_map>
#include <string>
#include <mutex>
#include <stack>
using namespace std;
mutex m_lock;
class some_data
{
int a;
string b;
public:
void do_something() {
a = 100;
}
int A() {
return a;
}
};
class data_wrapper {
private:
some_data data;
std::mutex m;
public:
template<typename Function>
void process_data(Function func) {
lock_guard<mutex> lg(m);
func(data); // 1 传递保护数据给用户函数
}
some_data getData() {
return data;
}
};
some_data* unprotected;
// 表示引用传递而不是拷贝传递
void malicious_function(some_data& protect_data) {
/* cout << "1:" << sizeof(protect_data) << endl;
cout << " 2:" << (&protect_data) << endl;*/
unprotected = &protect_data;
}
data_wrapper x;
void foo()
{
// 访问加锁函数后导致被保护数据的引用被泄露,从而使得被保护的数据不再安全。
cout << x.getData().A() << endl;
x.process_data(malicious_function);
unprotected -> do_something();
cout << x.getData().A() << endl;
}