zoukankan      html  css  js  c++  java
  • 无锁队列的原理与实现

    近期几天在思考无锁队列。看了相关文章,也读了一些博客,最后写了一份代码,代码实现对在多线程环境下对队列的读和写是不须要加锁的。

    代码例如以下所看到的:


    #include <windows.h>
    #pragma comment(lib, "Kernel32.lib")
    
    template<typename VT>
    class LcFQue{//lock free queue
    public:
    	struct QueNode{
    		QueNode *next;
    		VT 		value;
    	};
    public:
    	LcFQue();
    	~LcFQue();
    public:
    	void	EnQue(const VT& val);
    	VT		DeQue();
    private:
    	QueNode	*tail;
    	QueNode	*head;
    };
    
    template<typename VT>
    LcFQue<VT>::LcFQue(){
    	tail= head= new QueNode;
    	tail->value= -1;
    	tail->next= NULL;
    }
    
    template<typename VT>
    LcFQue<VT>::~LcFQue(){
    	QueNode* DelNode= head;
    	while(DelNode!= tail){
    		head= head->next;
    		delete DelNode;
    		DelNode= head;
    	}
    	delete DelNode;
    }
    
    template<typename VT>
    void LcFQue<VT>::EnQue(const VT& val){
    	QueNode* node	= new QueNode;
    	node->next		= NULL;
    	node->value		= val;
    	QueNode* tTail;
    	do{
    		tTail= tail;
    	}while(InterlockedCompareExchange((LONG*)&(tTail->next),(LONG)node,NULL)!= NULL);
    	InterlockedCompareExchange((LONG*)(&tail),(LONG)node,(LONG)tTail);
    }
    
    template<typename VT>
    VT LcFQue<VT>::DeQue(){
    	QueNode* tHead;
    	do{
    		tHead= head;
    		if(tHead->next==NULL){
    			return -1;
    		}
    	}while(InterlockedCompareExchange((LONG*)(&head),(LONG)(head->next),(LONG)tHead)!= (LONG)tHead);
    	return tHead->next->value;
    }
    
    #include <stdlib.h>
    #include <string.h>
    #include <iostream>
    #include <ctime>
    #include <cstdlib>
    using namespace std;
    LcFQue<int> que;
    
    
    int C[1000];
    DWORD WINAPI  EnQue(void* ParAddr);
    DWORD WINAPI  Deque(void* ParAddr);
    int main(){
    	memset(C,0,sizeof(C));
    	srand(time(NULL));
    	HANDLE hThread[10];
    	int AddEd[10];
    	for(int i= 0; i< 10; ++i){
    		AddEd[i]= i;
    	}
    	LPTHREAD_START_ROUTINE func;
    	for(int i= 0; i< 10; ++i){
    		if(i> 5){
    			func= Deque;
    		}else{
    			func= EnQue;
    		}
    		hThread[i]= ::CreateThread(
    			NULL,
    			0,
    			func,
    			AddEd+i,
    			0,
    			NULL
    			);
    	}
    	::WaitForMultipleObjects(10,hThread,TRUE,INFINITE);
    }
    
    DWORD WINAPI Deque(void* ParAddr){
    	while(true){
    		::Sleep(10);
    		int val= que.DeQue();
    		if(val==-1){
    			continue;
    		}
    		cout<<val<<'
    ';
    		++C[val];
    	}
    	return 0;
    }
    
    DWORD WINAPI  EnQue(void* ParAddr){
    	int* obj= (int*)ParAddr;
    	for(int i= 0; i< 100; ++i){
    		que.EnQue(i*5+*obj);
    		::Sleep(rand()%10);
    	}
    	return 0;
    }


  • 相关阅读:
    mysql复制那点事
    全排列问题
    56. Merge Interval
    2. Add Two Numbers
    20. Valid Parentheses
    121. Best Time to Buy and Sell Stock
    120. Triangle
    96. Unique Binary Search Trees
    91. Decode Ways
    72. Edit Distance
  • 原文地址:https://www.cnblogs.com/zhchoutai/p/6735973.html
Copyright © 2011-2022 走看看