Linux c++ shm 共享內存 傳輸圖像

之前寫了個項目的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;
} 

參考:

https://blog.csdn.net/stpeace/article/details/74834150

https://blog.csdn.net/qq_43762191/article/details/104995194

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章