API
头文件
#include <shm.h>
创建共享内存
int shmget(key_t key, size_t size, int shmflg);
key:键值,有效地为共享内存段命名
size:申请内存的大小
获取创建好的共享内存
void *shmat(int shm_id,const void *shm_addr, int shmflg);
shm_id:由shmget创建返回的共享内存id
shm_addr:指定物理共享内存映射到当前进程的此地址处,设为NULL时由OS决定
分离获得的共享内存
int shmdt(void *shm_addr);
shm_addr:shmat返回的本进程映射地址。
该函数只是让共享内存不再映射到本进程的地址范围内,并非释放共享内存
对共享内存进行操作
int shmctl(int shm_id, int command, struct shmid_ds *buf);
struct shmid_ds{
uid_t shm_perm.uid;
uid_t shm_perm.gid;
mode_t shm_perm.mode;
};
comman:
IPC_STAT
把shmid_ds中的数据设为共享内存的当前关联值
IPC_SET
如果有权限,把共享内存的内容设为shmid_ds中的数据
IPC_RMID
删除共享内存段
Console下的通信
头文件
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/shm.h>
#define TEXT_SZ 2048
struct shared_use_st{
int written_by_you;
char some_text[TEXT_SZ];
};
Producer.c
#include "shm_com.h"
int main()
{
int running = 1;
void *shared_memory = NULL;
struct shared_use_st *shared_stuff;
char buffer[BUFSIZ];
int shmid;
//创建共享内存
shmid = shmget((key_t)2222, sizeof(struct shared_use_st), 0666|IPC_CREAT);
if(shmid == -1){
fprintf(stderr, "shmget failed.\n");
return 1;
}
//获取共享内存映射
shared_memory = shmat(shmid, NULL ,0);
if(shared_memory == (void *)-1){
fprintf(stderr, "shmat failed.\n");
return 1;
}
printf("Memory attached at %X.\n", (int)shared_memory);
shared_stuff = (struct shared_use_st *)shared_memory;
while(running){
//等待消费者改写数据(表示有消费者存在)
while(shared_stuff->written_by_you == 1){
sleep(1);
printf("Waiting for client ...\n");
}
printf("Enter some text: ");
fgets(buffer, BUFSIZ, stdin);
strncpy(shared_stuff->some_text, buffer, TEXT_SZ);
shared_stuff->written_by_you = 1;
if(strncmp(buffer, "end", 3) == 0){
running = 0;
}
}
//解除内存映射关系
if(shmdt(shared_memory) == -1){
fprintf(stderr, "shmdt failed.\n");
return 1;
}
return 0;
}
Consumer.c
#include "shm_com.h"
int main()
{
int running = 1;
void *shared_memory = NULL;
struct shared_use_st *shared_stuff;
int shmid;
//创建共享内存
shmid = shmget((key_t)2222, sizeof(struct shared_use_st), 0666 | IPC_CREAT);
if(shmid == -1){
fprintf(stderr, "shmget failed.\n");
return 1;
}
//将共享内存地址映射到本进程
shared_memory = shmat(shmid, NULL, 0);
if(shared_memory == (void*)-1){
fprintf(stderr, "shmat failed.\n");
return 1;
}
printf("Memory attached at %X.\n", (int)shared_memory);
shared_stuff = (struct shared_use_st *)shared_memory;
shared_stuff -> written_by_you = 0;
while(running){
if(shared_stuff->written_by_you){
printf("You wrote:%s\n",shared_stuff->some_text);
sleep(rand()%4);
shared_stuff->written_by_you = 0;
if(strncmp(shared_stuff->some_text, "end", 3) == 0){
running = 0;
}
}
}
//分离共享内存
if(shmdt(shared_memory) == -1){
fprintf(stderr, "shmdt failed.\n");
return 1;
}
//释放共享内存
if(shmctl(shmid, IPC_RMID, 0) == -1){
fprintf(stderr, "shmctl(IPC_RMID) failed.\n");
return 1;
}
return 0;
}