#include <stdio.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
typedef struct{
unsigned int size;
char* content;
}myshmem;
typedef struct{
char name[128];
unsigned int size;
unsigned int avaliable;
char start[0];
}mem_head;
typedef enum{
READ = PROT_READ,
WRITE = PROT_WRITE
}MODE;
int mem_size;
char mem_name[128];
void* createHandle(const char* name, unsigned int size, MODE mode) // map a normal file as shared mem:
{
int fd,exist;
if(size < sizeof(mem_head)){
//printf("size must large than %d\n",sizeof(mem_head));
return NULL;
}
if(strlen(name) > 128){
printf("size of name must small than 128\n");
return NULL;
}
mem_size = size;
strcpy(mem_name,name);
fd = open(name, O_CREAT|O_RDWR, 00777);
if(fd < 0 ){
printf("open %s failed\n",name);
return NULL;
}
unsigned int len = size + sizeof(mem_head);
lseek(fd, len - 1, SEEK_SET);
write(fd,"",1);
char* handle = (char*)mmap( NULL, len, mode, MAP_SHARED, fd, 0 );
close( fd );
if(handle == NULL){
printf("mmap error\n");
return NULL;
}
printf("initialize over\n");
return (void*)(handle);
}
void destoryHandle(void* handle)
{
mem_head* head = (mem_head*)handle;
unsigned int len = head->size + sizeof(mem_head);
munmap(handle, len);
printf( "umap ok \n" );
}
int writeHandle(void* handle, const char* content, unsigned int len)
{
//printf("writeHandle :%s %d\n",content, len);
mem_head* head = (mem_head*)handle;
if(head != NULL ){
if(strcmp(head->name,mem_name)){
strcpy(head->name,mem_name);
head->avaliable = 0;
}
if(head->size != mem_size){
head->size = mem_size;
head->avaliable = 0;
}
} else{
printf("get mem_head failed\n");
return -1;
}
//printf("size:%d avaliable:%d name:%s\n",head->size,head->avaliable,head->name);
if(head->size < (head->avaliable + len)){
printf("share memory is full ,can not write\n");
return -1;
}
if(head->start == NULL){
printf("head->start is null\n");
return -1;
}
memcpy(head->start + head->avaliable , content, len);
//printf("write successed:%s\n",head->start);
head->avaliable += len;
return len;
}
int readHandle(void *handle, char* content, unsigned int offset, unsigned int len)
{
printf("readHandle\n");
mem_head* head = (mem_head*)handle;
if(head == NULL){
printf("head is null\n");
return -1;
}
if(strcmp(head->name,mem_name) || head->size != mem_size
|| head->avaliable <= offset){
printf("there is no content to read\n");
return 0;
}
//printf("name:%s size:%d avaliable:%d \n",head->name,head->size,head->avaliable);
if(head->start == NULL){
printf("start is NULL\n");
return -1;
}
unsigned int length = head->avaliable > (offset + len) ? len : (head->avaliable - offset);
printf("%d\n",length);
memcpy(content, head->start + offset, length);
printf("read over\n");
return length;
}
int main(int argc, char** argv)
{
int i = 0;
if(strstr(argv[0],"write")){
printf("start write\n");
char* handle = (char*)createHandle(argv[1],1024*3,WRITE);
if(handle == NULL){
printf("createHandle failed\n");
return -1;
}
while(writeHandle(handle, "hello",sizeof("hello") -1)){
sleep(1);
}
printf("write hello\n");
sleep(10);
destoryHandle(handle);
return 0;
}else{
printf("start read\n");
char* handle = (char*)createHandle(argv[1],1024*3,READ);
if(handle == NULL){
printf("getHandle failed\n");
return -1;
}
char buffer[10] = {0};
int len = 0;
while((len = readHandle(handle,buffer,len,sizeof(buffer))) > 0){
printf("read :%s\n",buffer);
sleep(1);
}
printf("readHandle:%d %s\n ",len,buffer);
destoryHandle(handle);
}
return 0;
}
mmap实现进程通讯
最新推荐文章于 2022-12-04 16:25:17 发布