linux 进程通信之共享内存机制C++代码实例

欢迎转载请注明出处:海漩涡

http://blog.csdn.net/tanhuifang520


linux 进程通信之共享内存机制C++代码实例


一、使用说明

只需包含share_memory.h

使用类通过名称和内存大小参数与其他进程共同使用一段内存



二、代码实例

1、通用类实现

share_memory.h

#ifndef __SHAREMEMORY_H__
#define __SHAREMEMORY_H__

#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ipc.h>
#include <sys/shm.h>

#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <semaphore.h>
#include <iostream>
#include <string.h>

typedef unsigned char  u8;
typedef unsigned short u16;
typedef unsigned int   u32;

class CShareMemory
{
public:
	CShareMemory(const char *name, u32 size);
	~CShareMemory();
	int PutToShareMem(const u8 *buffer, u32 length);
	int GetFromShareMem(u8 *buffer, u32 length);
private:
	void *CreateShareMemory(const char *name, u32 size);
	
	void SemLock ( void )
	{
		sem_wait ( m_sem );
	};
	
	void SemUnLock ( void )
	{
		sem_post ( m_sem );
	};
	
	sem_t *m_sem;
	u8 *m_shareMemory;
	u32 m_memSize;	
};

#endif

share_memory.cpp

#include "hd_share_mem.h"

CShareMemory::CShareMemory(const char *name, u32 size):m_memSize(size)
{	
	m_sem = sem_open(name, O_CREAT, 0X666, 1);
	if(SEM_FAILED == m_sem)
	{
		printf("sem_open error");
	}
	sem_unlink(name);

	SemLock();
	m_shareMemory = (u8 *)CreateShareMemory(name, m_memSize);
	SemUnLock();
}

/*
 * brief:  写入数据到共享内存
 * param1: buffer 写入数据buf
 * param2: length 写入数据长度
 * return: 返回写入数据的长度
**/
int CShareMemory::PutToShareMem(const u8 *buffer, u32 length)
{
	if(m_memSize < length)
	{
		printf("Input length[%u] exceeds memory length[%u] error", length, m_memSize);
		return -1;
	}

	SemLock();	
	memcpy(m_shareMemory, buffer, length);	
	SemUnLock();	
	return length;
}

/*
 * brief:  从共享内存读取数据
 * param1: buffer 读取数据buf
 * param2: length 读取数据长度
 * return: 返回读取数据的长度
**/
int CShareMemory::GetFromShareMem(u8 *buffer, u32 length)
{	
	if(m_memSize < length) // 获取数据越界
	{
		length = m_memSize;  
	}
	
	SemLock();
	memcpy(buffer, m_shareMemory, length);
	SemUnLock();
	return length;		
}

/*
 * brief:  创建共享内存
 * param1: name 
 * size:   创建内存大小
**/
void * CShareMemory::CreateShareMemory(const char *name, u32 size)
{
	int fd, shmid;
	void *memory;
	struct shmid_ds buf;
	char filename[32];

	snprintf(filename, 32, "/tmp/.%s", name);
	if((fd = open(filename, O_RDWR|O_CREAT|O_EXCL)) > 0)
	{
		close(fd);
	}
	
	shmid = shmget(ftok(filename, 'g'), size, IPC_CREAT);
	if (-1 == shmid)
    {
        perror("shmget err");
        return NULL;
    }
    //printf("shmid:%d \n", shmid);
	
	memory = shmat(shmid, NULL, 0);
	if ((void *)-1 == memory)
    {
        perror("shmget err");
        return NULL;
    }
	
	shmctl(shmid, IPC_STAT, &buf);
	if (buf.shm_nattch == 1)
	{
		memset(memory, 0, size);
	}	
	
	return memory;
}

CShareMemory::~CShareMemory()
{
	shmdt(m_shareMemory);
	sem_close(m_sem);
}


2、使用类例子

(1)进程1

main_1.cpp

#include "hd_share_mem.h"

int main()
{
	u8 buffer[] = {0x11, 0x12, 0x13, 0x14, 0x15};
	u32 length = sizeof(buffer);
		
	CShareMemory csm("txh", 1024);

	while(1)
	{
		for(int i=0; i<5; i++)
		{
			buffer[i]++;
		}
		
		csm.PutToShareMem(buffer,5);
		usleep(100000);
	}
	return 0;
}



(2)进程2

main_2.cpp

#include "hd_share_mem.h"

int main()
{
	char buffer1[] = {0x11, 0x12, 0x13, 0x14, 0x15};
	unsigned char buffer[5] = {0};
	unsigned int length = sizeof(buffer);
		
	CShareMemory csm("txh", 1024);

	while(1)
	{
		csm.GetFromShareMem(buffer,length);
		for(int i=0; i<length; i++)
		{
			printf("%x ", buffer[i]);
			/*if(buffer[i] != buffer1[i])
			{
				printf("T ---  buffer[%x]  buffer[%x]1\n", buffer[i] , buffer1[i]);
				return -1;
			}*/
		}
		printf("\n");
	}
	return 0;
}


三、编译运行

g++ share_mem.cpp main_1.cpp -lpthread -o main1

g++ share_mem.cpp main_1.cpp -lpthread -o main2


打开两个终端运行分别运行main1和mian2:注运行时加sudo获取root权限

即实现了两个进程间的共享内存通信





欢迎转载请注明出处:海漩涡

http://blog.csdn.net/tanhuifang520


猜你喜欢

转载自blog.csdn.net/tanhuifang520/article/details/80949782