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


  • 相关阅读:
    重构手法之简化函数调用【5】
    netstat命令
    Python使用wxpy模块实现微信两两群组消息同步
    format函数格式化显示的方法
    scrapy介绍及使用
    Linux常用命令复习
    Django实现博客项目
    Django中CKEditor富文本编译器的使用
    Django-admin站点管理的详细使用
    电脑修改密码后,git push 报错unable to access
  • 原文地址:https://www.cnblogs.com/zhchoutai/p/6735973.html
Copyright © 2011-2022 走看看