windows下多进程通信,基于共享内存环形队列实现

来源:互联网 发布:淘宝 618 大促 销售额 编辑:程序博客网 时间:2024/06/11 22:03

使用方式非常简单,需要的进程初始化类调用InitializeLock函数传入相同的字符串即可。可以多个进程使用PushString(),写入缓冲区,只允许一个进程进行调用PopString()读取,读取方面没有写保护锁,非线程安全。构造函数与析构函数看起来似乎不严谨,但不影响使用,有不对的地方望大牛提供指点。

测试代码用于获取通信所需的时间

进程读取缓冲区代码

 1 #include "stdafx.h" 2 #include <iostream> 3 #include <thread> 4 #include <Windows.h> 5 #include <sstream> 6 #include <istream> 7 #include "InterProcessCommunication.h" 8  9 inline long long  str2longlong(std::string str) 10 {  11     long long result;  12     std::istringstream is(str);  13     is >> result;  14     return result;  15 }    16 17 int _tmain(int argc, _TCHAR* argv[])18 {19     Sleep(1000);20      LARGE_INTEGER nEndTime;21      LARGE_INTEGER nFreq;22      QueryPerformanceFrequency(&nFreq);23     InterProcessCommunication t_MultiProcessLock;24     if(t_MultiProcessLock.InitializeLock("shared_memory"))25         std::cout<<"初始化成功!";26     std::string str;27     while(true)28     {                29         str=t_MultiProcessLock.PopString();30         QueryPerformanceCounter(&nEndTime); 31         long long start=str2longlong(str);32         double t=((double)(nEndTime.QuadPart-start))/nFreq.QuadPart*1000;33         printf("%s--通信时间%.6fms\n",str.c_str(),t);34         35     }36     return 0;37 }

 

进程写入缓冲区代码

 1 #include "stdafx.h" 2 #include <iostream> 3 #include <sstream> 4 #include <string>   5 using namespace std; 6 #include "InterProcessCommunication.h" 7  8 int _tmain(int argc, _TCHAR* argv[]) 9 {10     LARGE_INTEGER nFreq;11     InterProcessCommunication t_MultiProcessLock;12     if(t_MultiProcessLock.InitializeLock("shared_memory"))13         std::cout<<"初始化成功!";14      LARGE_INTEGER nBeginTime;15     unsigned char str1[10];16     QueryPerformanceFrequency(&nFreq);17     while(1)18     {        19         char   a[10];20         Sleep(100);21         string ss; 22         ostringstream os; 23         QueryPerformanceCounter(&nBeginTime); 24         os<<nBeginTime.QuadPart;  25         istringstream is(os.str());  26         is>>ss;  27         t_MultiProcessLock.PushString(ss.c_str());28         std::cout<<nBeginTime.QuadPart<<std::endl;29     }30     return 0;31 }

 

头文件

 1 #pragma once 2 #include <Windows.h> 3 #include <assert.h> 4 #include <iostream> 5 /** 6 * 7 *   @Description windows共享内存多进程高效字符串数据传输,进程安全 8 *  允许多个进程同时写入缓冲区,只允许一个进程进行读取,读取方式为阻塞式 9 *   @author        kellygod<kellygod95@gmail.com>10 *11 */12 #define BUFFER_MAX  4096     13 14 typedef struct _CircleBuffer{15     unsigned int head_pos;            16     unsigned int tail_pos;     17     unsigned char circle_buffer[BUFFER_MAX];  18 }CircleBuffer;19 20 typedef struct RWLock_s    21 {22     long long count;23     int state;24     HANDLE hRead;25     HANDLE hWrite;26     HANDLE hsynchronizedWrite;27     CircleBuffer buffer;28 } RWLock; 29 30 class InterProcessCommunication{31 public :32     InterProcessCommunication():m_bCreator(false){};33     ~InterProcessCommunication(){34         UnLock(); 35         if(m_bCreator) 36         {37             if(pRwLock!=NULL)    UnmapViewOfFile(pRwLock);                38             if(hMap!=NULL)    CloseHandle(hMap);                39         }40     };41     bool InitializeLock(const char* name);42     //阻塞模式43     std::string PopString();44     void PushString(const char* buff);45 46 private :47     RWLock* pRwLock;48     bool m_bCreator;49     HANDLE hMap;50     bool bufferPop(unsigned char* ch);51     void bufferPush(unsigned char ch);52     void ReadLock();53     void WriteLock();54     void UnLock();55     HANDLE hCondition;56 };

.cpp文件

  1 #include "stdafx.h"  2 #include "InterProcessCommunication.h"  3 #include <string>  4 enum  5 {  6     STATE_EMPTY = 0,  7     STATE_READ,  8     STATE_WRITE  9      10 }; 11  12 std::string InterProcessCommunication::PopString() 13 { 14     std::string buff; 15     unsigned char ch; 16     char* l=new char[256]; 17     char* str=l; 18     do{ 19         bufferPop(&ch); 20         *str++=(char)ch; 21     }while(ch!='\0'); 22      buff=std::string(l); 23     if(l!=NULL) 24         delete[] l; 25     l=NULL; 26     return buff; 27 } 28  29 void InterProcessCommunication::PushString(const char* buff) 30 { 31     unsigned char* str=(unsigned char*)buff; 32     int len=strlen(buff); 33     //必须使用同步锁,否则异步写入缓冲区会造成读取顺序混乱 34     WaitForSingleObject(pRwLock->hsynchronizedWrite,INFINITE); 35     for(int i=0;i<len;i++) 36     { 37         bufferPush(*str++); 38     } 39     bufferPush('\0'); 40     ReleaseMutex(pRwLock->hsynchronizedWrite); 41 } 42  43 bool InterProcessCommunication::InitializeLock(const char* name) 44 { 45     std::string sharedMemoryName="shared_memory"+std::string(name); 46     std::string readHandleName="read"+std::string(name); 47     std::string writeHandleName="write"+std::string(name); 48     std::string eventLockName="eventLockName"+std::string(name); 49     std::string synchronizedWrite="synchronizedWrite"+std::string(name); 50     hMap = ::OpenFileMappingA( FILE_MAP_WRITE, false, sharedMemoryName.c_str()); 51     if ( hMap == NULL )   52     { 53         int iErrCode = GetLastError(); 54         hMap=::CreateFileMappingA((HANDLE)-1,NULL,PAGE_READWRITE,0,sizeof(RWLock),sharedMemoryName.c_str());   55         if (hMap == 0 ) 56         { 57             int iErrCode = GetLastError(); 58             return false ; 59         }        60         m_bCreator=true; 61     } 62     RWLock* _pRwLock = (RWLock*)MapViewOfFile(hMap, FILE_MAP_ALL_ACCESS, 0, 0, 0); 63     HANDLE hRead=OpenMutexA(NULL,false,readHandleName.c_str()); 64     if(hRead==NULL) 65     { 66         hRead=CreateMutexA(NULL,false,readHandleName.c_str()); 67         if(hRead==NULL) return false; 68     } 69     HANDLE hWrite=OpenMutexA(NULL,false,writeHandleName.c_str()); 70     if(hWrite==NULL) 71     { 72         hWrite=CreateMutexA(NULL,false,writeHandleName.c_str()); 73         if(hWrite==NULL) return false; 74     } 75     hCondition=OpenEventA(EVENT_ALL_ACCESS ,NULL,eventLockName.c_str()); 76     if(hCondition==NULL) 77     { 78         hCondition=CreateEventA(NULL,false,false,eventLockName.c_str()); 79         if(hCondition==NULL) return false; 80     } 81     HANDLE hsynchronizedWrite=OpenMutexA(NULL,false,synchronizedWrite.c_str()); 82     if(hsynchronizedWrite==NULL) 83     { 84         hsynchronizedWrite=CreateMutexA(NULL,false,synchronizedWrite.c_str()); 85         if(hsynchronizedWrite==NULL) return false; 86     } 87      88         _pRwLock->hsynchronizedWrite=hsynchronizedWrite; 89         _pRwLock->hRead = hRead; 90         _pRwLock->hWrite = hWrite; 91         if(m_bCreator) 92         { 93             _pRwLock->count = 0; 94         } 95         _pRwLock->state = STATE_EMPTY; 96         pRwLock=_pRwLock; 97      98     return true; 99 }100 101 void InterProcessCommunication::ReadLock()102 {103     assert(NULL != pRwLock);104     WaitForSingleObject(pRwLock->hRead, INFINITE);105     pRwLock->count ++;106     if(1 == pRwLock->count){107         WaitForSingleObject(pRwLock->hWrite, INFINITE);108         pRwLock->state = STATE_READ;109     }110     ReleaseMutex(pRwLock->hRead);111 }112 113 void InterProcessCommunication::WriteLock()114 {115     assert(NULL != pRwLock);116     WaitForSingleObject(pRwLock->hWrite, INFINITE);117     pRwLock->state = STATE_WRITE;118 }119 void InterProcessCommunication::UnLock()120 {121     assert(NULL != pRwLock);122     if(STATE_READ == pRwLock->state){123         WaitForSingleObject(pRwLock->hRead, INFINITE);124         125         pRwLock->count--;126         if(0 == pRwLock->count){127             pRwLock->state = STATE_EMPTY;128             ReleaseMutex(pRwLock->hWrite);129         }130         ReleaseMutex(pRwLock->hRead);131     }else{132         pRwLock->state = STATE_EMPTY;133         ReleaseMutex(pRwLock->hWrite);134     }135     return;136 }137 138 bool InterProcessCommunication::bufferPop(unsigned char* _buf)139 {140     label1:141     if(pRwLock->buffer.head_pos==pRwLock->buffer.tail_pos) 142     {143         WaitForSingleObject(hCondition, 500);144         ResetEvent(hCondition);145         goto label1;146     }147     else148     {149         *_buf=pRwLock->buffer.circle_buffer[pRwLock->buffer.head_pos];150         ReadLock();151         if(++pRwLock->buffer.head_pos>=BUFFER_MAX)152             pRwLock->buffer.head_pos=0;153         UnLock();154         return true;155     }156 }157 void InterProcessCommunication::bufferPush(unsigned char _buf)158 {   159     pRwLock->buffer.circle_buffer[pRwLock->buffer.tail_pos]=_buf;   160     WriteLock();161     if(++pRwLock->buffer.tail_pos>=BUFFER_MAX)162         pRwLock->buffer.tail_pos=0;163     //缓冲区数据满后,尾指针与头指针指向同一个地方,原数据被覆盖 头指针向前移动    164     if(pRwLock->buffer.tail_pos==pRwLock->buffer.head_pos) 165         if(++pRwLock->buffer.head_pos>=BUFFER_MAX)166             pRwLock->buffer.head_pos=0;167     UnLock();168     SetEvent(hCondition);169 }

 

原创粉丝点击