参考: IBM Developer / 设计不使用互斥锁的并发数据结构
con_stack.hpp
#ifndef CON_STACK_H_
#define CON_STACK_H_
#include <atomic>
#include <vector>
using namespace std;
namespace eventsock{
template<typename T>
class StackNode{
private:
T m_value;
StackNode* m_next;
public:
StackNode(){
m_next = NULL;
}
StackNode(T value){
m_next = NULL;
m_value = value;
}
StackNode* next(){
return m_next;
}
void set_next(StackNode* next){
m_next = next;
}
T value(){
return m_value;
}
void set_value(T value){
m_value = value;
}
};
template<typename T>
class ConStack{
private:
StackNode<T>* m_top;
atomic_uint m_size;
public:
ConStack(): m_top(NULL), m_size(0){
}
void push(T value){
StackNode<T>* new_top = new StackNode<T>(value);
while(true){
new_top->set_next(m_top);
if(__sync_bool_compare_and_swap(&m_top, new_top->next(), new_top)){
m_size++;
break;
}
}
}
bool pop(){
StackNode<T>* old_top;
while(true){
old_top = m_top;
if(!old_top) return false;
if(m_top && __sync_bool_compare_and_swap(&m_top, old_top, old_top->next())){
break;
}
}
if(old_top){
m_size--;
delete old_top;
return true;
}
return false;
}
size_t size(){
return m_size;
}
bool empty(){
return m_top == NULL;
}
void output(){
StackNode<T> *ptr = m_top;
cout << "[" ;
while(ptr){
if(ptr != m_top){
cout << ",";
}
cout << ptr->value();
ptr = ptr->next();
}
cout << "]" << endl;
}
vector<T> to_vector(){
StackNode<T> *ptr = m_top;
vector<T> vec;
while(ptr){
vec.push_back(ptr->value());
ptr = ptr->next();
}
return vec;
}
};
}
#endif
测试例程:
#include <iostream>
#include "con_stack.hpp"
#include <vector>
#include <thread>
#include <atomic>
const int per_time = 5000;
// ConStack
eventsock::ConStack<int> con_stack;
void test_stack_push(int k){
for(int i = k * per_time; i < k * per_time + per_time; i++){
con_stack.push(i);
}
}
void test_stack_pop(int k){
for(int i = k * per_time; i < k * per_time + per_time; i++){
while(true){
if(con_stack.pop()) break;
//std::this_thread::sleep_for(std::chrono::seconds(1));
};
}
}
void test_con_stack(){
vector<thread> ths;
for(int i = 0; i < 10; i++){
ths.push_back(thread(test_stack_push, i));
ths.push_back(thread(test_stack_pop, i));
}
for(int i = 0; i < ths.size(); i++){
ths[i].join();
}
if(con_stack.empty()){
printf("ConStack success\n");
}else{
printf("ConStack fail\n");
}
}
int main(int argc, char* argv[])
{
test_con_stack();
return 0;
}