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;
    }


  • 相关阅读:
    VS2010安装Nuget提示签名不匹配错误解决办法
    vs2010不能正确加载 'VSTS for Database Professionals Sql Server Datatier Application'包
    [改编]如何理解.NET Framework(CLI,CLS,CTS,CLR,FCL,BCL)
    [导入]google翻译 lcs
    [导入]Visual SourceSafe中的权限 lcs
    [导入]EnterpriseLibrary 3.1 第一次下载.安装,读取数据库,绑定到控件成功. lcs
    [导入]在缓存时使用SqlCacheDependency lcs
    windows 2008 成功 激活 lcs
    [导入]DIV弹出对话框 lcs
    开发小记4 lcs
  • 原文地址:https://www.cnblogs.com/zhchoutai/p/6735973.html
Copyright © 2011-2022 走看看