不同进程间使用共享内存,调试的时候由于相同的一块物理内存在不同进程中的映射地址不同,所以有问题的时候找起来很麻烦,于是就想有没有办法把共享内存映射到不同进程中相同的用户空间地址上。
下面是想到的一个办法:
——没时间解释了,先放上代码,以后有时间再详细描述:
(也可以直接去gitee下载:https://gitee.com/vincent3016/shm_same_map/tree/master)
//resuse.c
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/shm.h>
#include <unistd.h>
#include <stdlib.h>
#include "common.h"
void *get_shared_memory(int size, void *p)
{
key_t key = 0;
int shmid = 0;
void *shm = NULL;
key = ftok("./key-file", 3);
if (key == -1) {
perror("failed to ftok.");
return NULL;
}
shmid = shmget(key, size, SHM_R | SHM_W | IPC_CREAT | IPC_EXCL);
if (shmid == -1) {
if (errno == EEXIST) {
shmid = shmget(key, 0, SHM_R | SHM_W);
} else {
printf("Err: shmget failed, errno:%d-%s.\n", errno, strerror(errno));
return NULL;
}
}
shm = shmat(shmid, p, 0);
if (shm == (void *) -1) {
printf("shmat error, errno: %d-%s.\n", errno, strerror(errno));
return NULL;
}
return shm;
}
long mkfifo_r()
{
int fd1;
char * myfifo = "/tmp/myfifo";
mkfifo(myfifo, 0666);
char buf[80];
fd1 = open(myfifo,O_RDONLY);
read(fd1, buf, 80);
close(fd1);
long l = atol(buf);
return l;
}
int main()
{
long l = mkfifo_r();
shm_t *shm_p = (shm_t *)get_shared_memory(0, (void *)l);
printf("shm_p = %p, shm_p->a = %d, shm_p->f = %.2f, shm_p->buf = %s\n", shm_p, shm_p->a, shm_p->f, shm_p->buf);
}
//create.c
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/shm.h>
#include <unistd.h>
#include "common.h"
void *get_shared_memory(int size)
{
key_t key = 0;
int shmid = 0;
void *shm = NULL;
key = ftok("./key-file", 3);
if (key == -1) {
perror("failed to ftok.");
return NULL;
}
shmid = shmget(key, size, SHM_R | SHM_W | IPC_CREAT | IPC_EXCL);
if (shmid == -1) {
if (errno == EEXIST) {
shmid = shmget(key, 0, SHM_R | SHM_W);
} else {
printf("Err: shmget failed, errno:%d-%s.\n", errno, strerror(errno));
return NULL;
}
}
shm = shmat(shmid, NULL, 0);
if (shm == (void *) -1) {
printf("shmat error, errno: %d-%s.\n", errno, strerror(errno));
return NULL;
}
return shm;
}
int mkfifo_w(void *p)
{
int fd;
char * myfifo = "/tmp/myfifo";
mkfifo(myfifo, 0666);
char buf[80];
fd = open(myfifo, O_WRONLY);
sprintf(buf, "%ld", (long)p);
write(fd, buf, strlen(buf) + 1);
close(fd);
return 0;
}
int main()
{
shm_t *shm_p = (shm_t *)get_shared_memory(sizeof(shm_t));
printf("shm_p = %p\n", shm_p);
shm_p->a = 666;
shm_p->f = 3.14;
strcpy(shm_p->buf, "hello world");
mkfifo_w(shm_p);
return 0;
}
//common.h
#ifndef __COMMON_H__
#define __COMMON_H__
typedef struct {
int a;
float f;
char buf[128];
} shm_t;
#endif
编译:
gcc -o resuse resuse.c
gcc -o create create.c