之前寫了個項目的demo,windows平臺下python實現的,由於效率問題,用了多進程,進程間的通訊是依賴於multiprocessing manager.
前段時間,突然說要把項目移植到Liunx平臺下,而且要用c++來實現。(我直接暈過去了,這和重寫一遍有什麼區別?
遇到的第一個問題就是怎麼解決進程間通信,百度之後決定使用共享內存。因爲大家都說它的效率最快。
我用的是shm,關於它的介紹有很多,我這裏就不解釋了。
server.cpp ,往內存裏寫,int flag起到一個讀寫保護的作用,可以用鎖來代替。
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/shm.h>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
#include <vector>
#include <string>
#define IMAGE_SIZE 480*640*3 //圖片大小
using namespace std;
typedef struct _BOX
{
int flag;
char ch[IMAGE_SIZE];//之前用了cv::Mat不行,因爲無法在結構體裏初始化大小
}Box;
int main()
{
int shmid = shmget((key_t)1275, sizeof(Box), 0666|IPC_CREAT);
void *shm = shmat(shmid, (void*)0, 0);
Box *pBox = (Box*)shm;
pBox->flag = 0;
int i = 0;
while(1)
{
while(pBox->flag == 0)
{
getchar();
cv::Mat Img=cv::imread("/home/qogori/shared_memory/src/dst.bmp",cv::IMREAD_COLOR);
int size = Img.cols * Img.rows * Img.channels();
if(Img.data== nullptr)//nullptr是c++11新出現的空指針常量
{
printf("圖片文件不存在\n");
return 0;
}
printf("Memory attached at %p\n", (int *)(shm));
char *from = (char*)Img.data;
memcpy(pBox->ch, from, size);
pBox->flag = 1;
}
}
shmdt(shm);
return 0;
}
client.cpp ,從內存讀數據
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/shm.h>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
#define IMAGE_SIZE 640*480*3 //圖片大小
using namespace std;
typedef struct _BOX
{
int flag;
char ch[IMAGE_SIZE];
}Box;
int main()
{
int shmid = shmget((key_t)1275, sizeof(Box), 0666|IPC_CREAT);
void *shm = shmat(shmid, (void*)0, 0);
Box *pBox = (Box*)shm;
size_t sizeofbuf;
while(1)
{
if(pBox->flag == 1)
{
cv::Mat cvoutImg = cv::Mat(480,640,CV_8UC3,cv::Scalar(255, 255, 255));//bufHight,bufWidth
int size = cvoutImg.cols * cvoutImg.rows * cvoutImg.channels();
memcpy((char*)cvoutImg.data, pBox->ch,size);
cv::imshow("xx",cvoutImg);
cv::waitKey(1000);
pBox->flag = 0;
}
}
shmdt(shm);
shmctl(shmid, IPC_RMID, 0);
return 0;
}
參考: