https://en.cppreference.com/w/cpp/atomic/memory_order
stack.h
#include <atomic>
using namespace std;
template<typename T>
class stack
{
template<typename D>
struct node
{
D data;
node* next;
node(const D& data):data(data), next(nullptr){}
};
std::atomic<node<T>*> head;
public:
stack():head(nullptr){}
void push(const T& data)
{
node<T>* new_node = new node<T>(data);
new_node->next = head.load(std::memory_order_relaxed);
while(!head.compare_exchange_weak(new_node->next, new_node, std::memory_order_release, std::memory_order_relaxed));
}
bool try_pop(T& data)
{
auto result = head.load(std::memory_order_relaxed);
while(result != nullptr && !head.compare_exchange_weak(result, result->next,std::memory_order_release,std::memory_order_relaxed));
if (result != nullptr)
{
data = result->data;
return true;
}
else
{
return false;
}
}
};
main.cpp 创建2个push线程,2个pop线程
#include <iostream>
#include "stack.h"
#include <thread>
using namespace std;
stack<int> s;
std::atomic<int> count(0);
const int Max = 10000;
void do_push()
{
for(int i=0;i<Max;++i)
{
s.push(i);
}
}
void do_pop()
{
while(count != Max *2)
{
int out = 0;
while (s.try_pop(out))
{
cout<<"pop:"<<out<<",count:"<<++count<<endl;
}
}
}
int main()
{
std::thread t1(do_push);
std::thread t2(do_push);
std::thread t3(do_pop);
std::thread t4(do_pop);
t1.join();
cout<<"quit t1"<<endl;
t2.join();
cout<<"quit t2"<<endl;
t3.join();
cout<<"quit t3"<<endl;
t4.join();
cout<<"quit t4"<<endl;
return 0;
}
编译命令
g++ --std=c++11 -g main.cpp -o main -pthread