编程小白,第一次发CSDN博客 。近期想要实现本机c++与python多进程间数据传输,找到了共享内存的方法,搜集借鉴了网络上大佬们的实现方法,最后自认为以最简单的方式实现了python进程间交换数据,python与c++之间交换数据以及c++进程之间交换数据。
c++和python都有类似的文件映射的功能,c++中为windows.h中的filemapping库,python则可以通过mmap包来实现。
其原理为使用计算机中的一个位置或文件,将其映射到内存中,这一部分内存就有了具体的名字或者位置,在这个计算机上运行的所有程序(进程)都可以访问这块内存,因此实现不同程序、进程之间的通讯。
在计算机内存中仅可写入字符串,因此下一步需要将我们的数据进行修饰,可以使用json包进行修饰和翻译,这样就可以达到复杂的数据交流,当然,这部分工作量通常较大,但可以实现一些自动模式,内存也可以自动扩充。
python程序写入内存:
import mmap
import json
#写入一次
def send(s):
s=str(len(s))+' '+s+100*' '
infosize=len(s)+1
byte=s.encode(encoding='UTF-8')
#从头读取内存,不然的话会接着上次的内存位置继续写下去,这里是从头覆盖。
shmem=mmap.mmap(0,1000,file_name,mmap.ACCESS_WRITE)
shmem.write(byte)
#首先需要开内存,在函数中会自动回收内存。
file_name='global_share_memory'
shmem=mmap.mmap(0,1000,file_name,mmap.ACCESS_WRITE)
#循环写入
while True:
s='send1'
while s=='':
s=input()
if s=='stop':
break
send(s)
python程序读取共享内存:
import mmap
#共享内存名称
file_name='global_share_memory'
#读取一次内存
def recieve():
shmem=mmap.mmap(0,100,file_name,mmap.ACCESS_READ)
s=str(shmem.read(shmem.size()).decode("utf-8"))
#vs2012早期版本会有截断符和开始符号,需要提取有用字符串
es='\\x00'#字符条件截断,还没有设计开始endstring
if s.find(es)==-1:
print(s)
else:
sn=s[:s.index(es)]
print(sn)
#按一次回车读取一次
while True:
s=input()
recieve()
C++程序的写入和读取:
#include
#include
#include
#include
#include
using namespace std;
void send();
void receieve();
int main() {
receieve();
//send();
}
void receieve() {
SYSTEMTIME sys_time;
LPVOID pBuffer;
LPVOID pEBuffer = NULL;
string strMapName("global_share_memory");
HANDLE hMap = NULL;
GetLocalTime(&sys_time);
printf("%4d/%02d/%02d %02d:%02d:%02d.%03d ", sys_time.wYear, sys_time.wMonth, sys_time.wDay, sys_time.wHour, sys_time.wMinute, sys_time.wSecond, sys_time.wMilliseconds);
//cout << typeid(sys_time.wSecond).name() << endl;
#循环读取:
while (TRUE)
{
#打开共享内存,获得句柄,类似于获得内存地址。
hMap = OpenFileMapping(FILE_MAP_ALL_ACCESS, 0, L"global_share_memory");
if (hMap == NULL) {
cout << "can't open filemapping" << endl;
Sleep(2000);
continue;
}
#打开内存映射,读取共享中的内容,pBuffer指向这些内容,即修改pBuffer的值,就是修改共享内存的值。
pBuffer = MapViewOfFile(hMap, FILE_MAP_ALL_ACCESS, 0, 0, 0);
if ((char*)pBuffer != NULL)cout << (char*)pBuffer << endl;
GetLocalTime(&sys_time);
printf("%4d/%02d/%02d %02d:%02d:%02d.%03d ", sys_time.wYear, sys_time.wMonth, sys_time.wDay, sys_time.wHour, sys_time.wMinute, sys_time.wSecond, sys_time.wMilliseconds);
cout << endl;
//system("pause");
Sleep(1);#每一秒读取一次,可以设置为外部循环,取消这个大循环设置为单次读取。
}
}
void send() {
SYSTEMTIME sys_time;
LPVOID pBuffer;
string strMapName("global_share_memory");
HANDLE hMap = NULL;
hMap = OpenFileMapping(FILE_MAP_ALL_ACCESS, 0, L"global_share_memory");
if (hMap == NULL) {#没有这个内存就自己创建一个。
cout << "no memorymap,i will creat a new one" << endl;
hMap = CreateFileMapping(NULL, NULL, PAGE_READWRITE, 0, 0X1000, L"global_share_memory");
}
#在这里,修改pBuffer的值就可以改变共享内存中的内容。
pBuffer = MapViewOfFile(hMap, FILE_MAP_ALL_ACCESS, 0, 0, 0);
char s[100];
gets_s(s);
#只是单纯的把字符串拷贝给pBuffer就可以达到修改共享内存的值,pBuffer就是共享内存中的值。
strcpy((char*)pBuffer, s);
system("pause");
}