A、posix内存映射文件例子
posix_file.c文件
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define FILE_MODE (S_IRUSR | S_IWUSR)
const char shmfile[] = "./tmp.shm";
const int size = 100;
struct namelist {
int id;
char name[20];
};
int main(void)
{
int fd, pid, status;
int *ptr;
struct stat stat;
int flags = O_RDWR | O_CREAT;
fd = open(shmfile, flags, FILE_MODE);
ftruncate(fd, size);
ptr = (int *)mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
close(fd);
pid = fork();
if (pid == 0) { // child process
printf("Child %d: start\n", getpid());
fd = open(shmfile, flags, FILE_MODE);
fstat(fd, &stat);
ptr = (int *)mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
close(fd);
struct namelist tmp;
// store total num in ptr[0];
*ptr = 3;
ptr++;
struct namelist *cur = (struct namelist *)ptr;
// store items
tmp.id = 1;
strcpy(tmp.name, "Nellson");
*cur++ = tmp;
tmp.id = 2;
strcpy(tmp.name, "Daisy");
*cur++ = tmp;
tmp.id = 3;
strcpy(tmp.name, "Robbie");
*cur++ = tmp;
exit(0);
} else { // parent process
sleep(1);
struct namelist tmp;
int i;
int total = *ptr;
printf("There is %d item in the shm\n", total);
ptr++;
struct namelist *cur = (struct namelist *)ptr;
for (i = 0; i< total; i++) {
tmp = *cur;
printf("%d: %s\n", tmp.id, tmp.name);
cur++;
}
printf("\n");
waitpid(pid, &status, 0);
}
printf("Parent %d get child status:%d\n", getpid(), status);
return 0;
}
CC = gcc
WORKDIR =
INCLUDES =
LIBS =
LINKS =
TARGET = posix_file
src=$(wildcard *.c ./callback/*.c)
C_OBJS=$(patsubst %.c, %.o,$(src))
#C_OBJS=$(dir:%.c=%.o)
compile:$(TARGET)
$(C_OBJS):%.o:%.c
$(CC) $(CFLAGS) $(INCLUDES) -o $*.o -c $*.c
$(TARGET):$(C_OBJS)
$(CC) -o $(TARGET) $^ $(LIBS) $(LINKS)
@echo
@echo Project has been successfully compiled.
@echo
install: $(TARGET)
cp $(TARGET) $(INSTALL_PATH)
uninstall:
rm -f $(INSTALL_PATH)/$(TARGET)
rebuild: clean compile
clean:
rm -rf *.o $(TARGET) *.log *~
B、posix共享内存对象例子
这个例子是两个没有亲缘关系的进程,分成两个文件server.c和client.c,两个进程间使用信号量进行同步。
server.c文件
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define FILE_MODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)
//计数器结构体
struct shmstruct {
int count;
};
//同步有名信号量
sem_t *mutex;
int main(int argc,char *argv[])
{
int fd;
struct shmstruct *ptr;
if(argc != 3) {
printf("usage: server .\n");
exit(0);
}
//防止所需共享内存区对象已经存在
shm_unlink(argv[1]);
//创建一个新的共享内存区对象
if((fd = shm_open(argv[1], O_RDWR | O_CREAT | O_EXCL, FILE_MODE)) == -1) {
perror("shm_open error");
exit(-1);
}
//指定新创建的共享内存区对象的大小
ftruncate(fd, sizeof( struct shmstruct));
//将新创建的共享内存区映射到调用进程的地址空间
if((ptr = mmap(NULL, sizeof(struct shmstruct), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)) == MAP_FAILED) {
perror("mmap error");
exit(-1);
}
//关闭对象描述符
close(fd);
//防止所需的信号量已经存在
sem_unlink(argv[2]);
//创建有名信号量,作为互斥锁用
if((mutex = sem_open(argv[2], O_CREAT|O_EXCL, FILE_MODE, 1)) == SEM_FAILED) {
perror("sem_open error");
exit(-1);
}
//关闭信号量
sem_close(mutex);
exit(0);
}
CC = gcc
WORKDIR =
INCLUDES =
LIBS =
LINKS = -lrt
TARGET = server
src=$(wildcard *.c ./callback/*.c)
C_OBJS=$(patsubst %.c, %.o,$(src))
#C_OBJS=$(dir:%.c=%.o)
compile:$(TARGET)
$(C_OBJS):%.o:%.c
$(CC) $(CFLAGS) $(INCLUDES) -o $*.o -c $*.c
$(TARGET):$(C_OBJS)
$(CC) -o $(TARGET) $^ $(LIBS) $(LINKS)
@echo
@echo Project has been successfully compiled.
@echo
install: $(TARGET)
cp $(TARGET) $(INSTALL_PATH)
uninstall:
rm -f $(INSTALL_PATH)/$(TARGET)
rebuild: clean compile
clean:
rm -rf *.o $(TARGET) *.log *~
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define FILE_MODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)
struct shmstruct {
int count;
};
sem_t *mutex;
int main(int argc,char *argv[])
{
int fd,i,nloop;
pid_t pid;
struct shmstruct *ptr;
if(argc != 4) {
printf("usage: posix_mem1 .\n");
exit(0);
}
nloop = atoi(argv[3]);
//打开共享内存区
if((fd = shm_open(argv[1], O_RDWR, FILE_MODE)) == -1) {
perror("shm_open error\n");
exit(0);
}
//将共享内存区映射到进程地址空间
if((ptr = mmap(NULL, sizeof(struct shmstruct), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)) == MAP_FAILED) {
perror("mmap error\n");
exit(-1);
}
close(fd);
//打开信号量
if((mutex = sem_open(argv[2], 0)) == SEM_FAILED) {
printf("open sem:%s error\n", argv[2]);
exit(-1);
}
pid = getpid();
sem_wait(mutex); //锁住信号量
for(i=0;icount++);
}
sem_post(mutex); //释放信号量
exit(0);
}
CC = gcc
WORKDIR =
INCLUDES =
LIBS =
LINKS = -lrt
TARGET = client
src=$(wildcard *.c ./callback/*.c)
C_OBJS=$(patsubst %.c, %.o,$(src))
#C_OBJS=$(dir:%.c=%.o)
compile:$(TARGET)
$(C_OBJS):%.o:%.c
$(CC) $(CFLAGS) $(INCLUDES) -o $*.o -c $*.c
$(TARGET):$(C_OBJS)
$(CC) -o $(TARGET) $^ $(LIBS) $(LINKS)
@echo
@echo Project has been successfully compiled.
@echo
install: $(TARGET)
cp $(TARGET) $(INSTALL_PATH)
uninstall:
rm -f $(INSTALL_PATH)/$(TARGET)
rebuild: clean compile
clean:
rm -rf *.o $(TARGET) *.log *~
四、 SYSTEM V共享内存
1)函数说明例子是两个没有亲缘关系的进程,使用互斥锁进行同步,分成两个文件,一个负责读一个负责写。
共用的头文件sm_common.h
#ifndef __SM_COMMON_H__
#define __SM_COMMON_H__
#include
#define SM_BUF_SIZE 1024
#define SM_ID 0x1122
struct sm_msg {
int flag;
pthread_mutex_t sm_mutex;
char buf[SM_BUF_SIZE];
};
#endif
shm_read.c文件
#include
#include
#include
#include
#include
#include "sm_common.h"
int main(void)
{
int shm_id = -1;
int ret = -1;
int key = -1;
int running = 1;
struct sm_msg *msg = NULL;
void *shared_memory = NULL;
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
//key = ftok( "./sm_common.h", 1 );
//printf("key: %d\n", key);
shm_id = shmget((key_t)SM_ID, sizeof(struct sm_msg), 0666|IPC_CREAT);
if(shm_id < 0) {
printf("fail to shmget\n");
exit(1);
}
shared_memory = shmat(shm_id, NULL, 0);
if (shared_memory == NULL) {
printf("Failed to shmat\n");
exit(1);
}
msg = (struct sm_msg *)shared_memory;
msg->flag = 0;
pthread_mutex_init(&msg->sm_mutex, &attr);
while (running) {
pthread_mutex_lock(&msg->sm_mutex);
if (msg->flag == 1) {
printf("Read message: %s\n", msg->buf);
msg->flag = 0;
pthread_mutex_unlock(&msg->sm_mutex);
if (strncmp(msg->buf, "exit", 4) == 0) {
running = 0;
}
} else {
printf("No available data to read, sleep...\n");
pthread_mutex_unlock(&msg->sm_mutex);
sleep(2);
}
}
ret = shmdt(shared_memory);
if (ret < 0) {
printf("Failed to shmdt\n");
exit(1);
}
if(shmctl(shm_id, IPC_RMID, 0) < 0) {
printf("failed to shmctl\n");
exit(1);
}
return 0;
}
Makefile文件
CC = gcc
WORKDIR =
INCLUDES =
LIBS =
LINKS = -lpthread
TARGET = shm_read
src=$(wildcard *.c ./callback/*.c)
C_OBJS=$(patsubst %.c, %.o,$(src))
#C_OBJS=$(dir:%.c=%.o)
compile:$(TARGET)
$(C_OBJS):%.o:%.c
$(CC) $(CFLAGS) $(INCLUDES) -o $*.o -c $*.c
$(TARGET):$(C_OBJS)
$(CC) -o $(TARGET) $^ $(LIBS) $(LINKS)
@echo
@echo Project has been successfully compiled.
@echo
install: $(TARGET)
cp $(TARGET) $(INSTALL_PATH)
uninstall:
rm -f $(INSTALL_PATH)/$(TARGET)
rebuild: clean compile
clean:
rm -rf *.o $(TARGET) *.log *~
shm_write.c文件
#include
#include
#include
#include
#include
#include "sm_common.h"
int main(void)
{
int shm_id = -1;
int ret = -1;
int key = -1;
int running = 1;
struct sm_msg *msg = NULL;
void *shared_memory = NULL;
//key = ftok( "./sm_common.h", 1 );
//printf("key: %d\n", key);
shm_id = shmget((key_t)SM_ID, sizeof(struct sm_msg), 0666|IPC_CREAT);
if(shm_id < 0) {
perror("fail to shmget");
exit(1);
}
shared_memory = shmat(shm_id, NULL, 0);
if (shared_memory == NULL) {
perror("Failed to shmat");
exit(1);
}
msg = (struct sm_msg *)shared_memory;
char buf[32];
while (running) {
printf("wait lock\n");
pthread_mutex_lock(&msg->sm_mutex);
printf("get lock\n");
if(msg->flag == 1) {
printf("Wait for other process's reading\n");
pthread_mutex_unlock(&msg->sm_mutex);
sleep(2);
} else {
printf("Please input data\n");
fgets(buf, 32, stdin);
printf("Write msg: %s\n", buf);
strncpy(msg->buf, buf, sizeof(buf));
msg->flag = 1;
if (strncmp(msg->buf, "exit", 4) == 0) {
running = 0;
}
pthread_mutex_unlock(&msg->sm_mutex);
}
}
ret = shmdt(shared_memory);
if (ret < 0) {
perror("Failed to shmdt");
exit(1);
}
#if 0 //Do this in server.
if(shmctl(shm_id, IPC_RMID, 0) < 0)
{
perror("failed to shmctl");
exit(1);
}
#endif
return 0;
}
CC = gcc
WORKDIR =
INCLUDES =
LIBS =
LINKS = -lpthread
TARGET = shm_write
src=$(wildcard *.c ./callback/*.c)
C_OBJS=$(patsubst %.c, %.o,$(src))
#C_OBJS=$(dir:%.c=%.o)
compile:$(TARGET)
$(C_OBJS):%.o:%.c
$(CC) $(CFLAGS) $(INCLUDES) -o $*.o -c $*.c
$(TARGET):$(C_OBJS)
$(CC) -o $(TARGET) $^ $(LIBS) $(LINKS)
@echo
@echo Project has been successfully compiled.
@echo
install: $(TARGET)
cp $(TARGET) $(INSTALL_PATH)
uninstall:
rm -f $(INSTALL_PATH)/$(TARGET)
rebuild: clean compile
clean:
rm -rf *.o $(TARGET) *.log *~