无锁栈实现一例
[cpp]
<SPAN style="FONT-FAMILY: 'Microsoft YaHei'; FONT-SIZE: 18px">一、何谓无锁队列</SPAN>
一、何谓无锁队列无锁队列,顾名思义,即不需要加锁的队列;之所以不需要额外加锁,是因为其本身已经是线程安全的。
二、为什么要在队列中集成线程安全的机制?
这里我想采用对比的方式来讲述。有锁队列,这可能是最简单的一种队列了,比如我们在多线程情况下使用标准STD的deque,那么毫无疑问需要对其加锁。加锁其实是将协调过程交给了操作系统来管理,但无锁队列却是在CPU层面就做到了协调,所以在效率上会高很多。更详细的解释请参见http://www.searchtb.com/2012/10/introduction_to_disruptor.html
三、如何实现?
这里主要是采用ACS。
1. 定义队列。这里由于测试的缘故,队列节点内的数据比较简单。
[cpp]
/* ACS node define. */
typedef struct acs_node_t {
std::string id;
int index;
struct acs_node_t* next;
} acs_node_t;
/* ACS deque define. */
typedef struct acs_deque_t {
struct acs_node_t head;
struct acs_node_t* tail;
} acs_deque_t;
/* ACS node define. */
typedef struct acs_node_t {
std::string id;
int index;
struct acs_node_t* next;
} acs_node_t;
/* ACS deque define. */
typedef struct acs_deque_t {
struct acs_node_t head;
struct acs_node_t* tail;
} acs_deque_t;
2. 定义接口。这里定义了队列初始化,入队列以及出队列三个接口。
[cpp]
void acs_deque_init(acs_deque_t* deq);
int acs_deque_empty(acs_deque_t* deq);
void acs_deque_push(acs_deque_t* deq, acs_node_t* node);
acs_node_t* acs_deque_pop(acs_deque_t* deq);
void acs_deque_init(acs_deque_t* deq);
int acs_deque_empty(acs_deque_t* deq);
void acs_deque_push(acs_deque_t* deq, acs_node_t* node);
acs_node_t* acs_deque_pop(acs_deque_t* deq);
3.下面是接口的实现。
[html]
void acs_deque_init(acs_deque_t* deq)
{
if (deq) {
deq->tail = &deq->head;
deq->head.next = NULL;
}
}
int acs_deque_empty(acs_deque_t* deq)
{
if (!deq)
return 1;
return deq->head.next == NULL;
}
void acs_deque_push(acs_deque_t* deq, acs_node_t* node)
{
acs_node_t* q = NULL;
do {
q = deq->tail;
} while (InterlockedCompareExchangePointer((PVOID*)&q->next, 0, node) != q->next);
InterlockedCompareExchangePointer((PVOID*)&deq->tail, q, node);
}
acs_node_t* acs_deque_pop(acs_deque_t* deq)
{
acs_node_t* q = NULL;
do {
q = deq->head.next;
if (q == NULL)
return NULL;
} while (InterlockedCompareExchangePointer((PVOID*)&deq->head.next, q, q->next) != deq->head.next);
return q;
}
void acs_deque_init(acs_deque_t* deq)
{
if (deq) {
deq->tail = &deq->head;
deq->head.next = NULL;
}
}
int acs_deque_empty(acs_deque_t* deq)
{
if (!deq)
return 1;
return deq->head.next == NULL;
}
void acs_deque_push(acs_deque_t* deq, acs_node_t* node)
{
acs_node_t* q = NULL;
do {
q = deq->tail;
} while (InterlockedCompareExchangePointer((PVOID*)&q->next, 0, node) != q->next);
InterlockedCompareExchangePointer((PVOID*)&deq->tail, q, node);
}
acs_node_t* acs_deque_pop(acs_deque_t* deq)
{
acs_node_t* q = NULL;
do {
q = deq->head.next;
if (q == NULL)
return NULL;
} while (InterlockedCompareExchangePointer((PVOID*)&deq->head.next, q, q->next) != deq->head.next);
return q;
}接口采用了Windows的ACS函数,当然你也可以将其更改为linux版本的ACS函数。
4. 其他代码为测试代码,全部代码为
[cpp]
#include <stdio.h>
#include <string>
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <deque>
static const int knThreadCount = 4;
static const int knMaxNodeCount = 50000;
static const int knPopedCount = 5000;
/* ACS node define. */
typedef struct acs_node_t {
std::string id;
int index;
struct acs_node_t* next;
} acs_node_t;
/* ACS deque define. */
typedef struct acs_deque_t {
struct acs_node_t head;
struct acs_node_t* tail;
} acs_deque_t;
typedef struct DequeData {
std::string id;
int index;
} DequeData;
typedef std::deque<DequeData*> StdDeque;
CRITICAL_SECTION g_stdcs;
int g_aes_cost_time = 0;
int g_std_cost_time = 0;
class HRTimer {
public:
HRTimer();
~HRTimer() {}
double GetFrequency(void);
void StartTimer(void);
double StopTimer(void);
private:
LARGE_INTEGER start_;
LARGE_INTEGER stop_;
double frequency_;
};
HRTimer::HRTimer()
: start_(),
stop_(),
frequency_(0.f)
{
frequency_ = this->GetFrequency();
}
double HRTimer::GetFrequency(void)
{
LARGE_INTEGER proc_freq;
if (!::QueryPerfor
补充:软件开发 , C++ ,