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 }
阅读全文
0 0
- windows下多进程通信,基于共享内存环形队列实现
- Linux进程间通信-基于内存(共享队列)
- Linux c 基于内存的进程通信—共享内存、共享队列(消息队列)
- linux下的多进程通信(IPC)原理及实现方案(管道、队列、信号量、共享内存)
- Windows or Linux环境下利用“共享内存”实现进程间通信的C/C++代码
- Windows 进程间通信 共享内存(FileMapping)_C#实现
- Linux——基于共享内存 消息队列和基于Socket的进程间的通信
- unix下使用共享内存实现进程间通信
- windows 进程间通信(共享内存)
- windows 进程间通信(共享内存)
- Windows进程间通信之共享内存
- windows 进程间通信(共享内存)
- Windows进程间通信-共享内存
- windows编程之进程通信:内存共享
- Windows进程间共享内存通信实例
- Windows进程间通信--共享内存
- Windows进程通信——共享内存
- Windows进程间通信-共享内存
- python爬虫0.3
- 断言
- python0.4
- 初学nlp&nn
- 《Machine Learning in&…
- windows下多进程通信,基于共享内存环形队列实现
- 华为2017.8月笔试题
- H5多图片压缩加水印上传
- 欢迎使用CSDN-markdown编辑器
- 【机器学习基础】准确率(Accuracy), 精确率(Precision), 召回率(Recall)和F1-Measure
- 啊
- java学习笔记06
- mysql如何利用Navicat 导出和导入数据库
- 利用solr实现商品的搜索功能