基于Linux内核的共享内存C语言示例
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/stat.h>
#include <sys/shm.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <strings.h>
#include <sys/wait.h>
int main()
{
//步骤1,获得句柄
key_t key = ftok("./file", 9);
if(key < 0)
{
perror("ftok");
exit(1);
}
printf("key = 0x%x\n", key);
//步骤2,创建系统级共享内存,共20个字节(实际开辟了1页,即4096个字节),获得标识符
int shmid = shmget(key, 20, IPC_CREAT | 0666);
if(shmid < 0)
{
perror("shmget");
exit(1);
}
printf("shmid = %d\n", shmid);
//步骤3,将shmid所指代的共享内存映射到当前进程,NULL表示自动选择当前进程里可用的地址。
char *shmp = (char*) shmat(shmid, NULL, 0);//将void*强转成char*
if((intptr_t)shmp == -1)
{
perror("shmp");
exit(1);
}
printf("shmp's addr is %p\n", shmp);
bzero(shmp, 20);//将shmp清空
//通过snprintf(shmp, 20, "hello\n")写进shmp中的内容,存进了内核中,不会因为程序结束而抹去。
//就算程序结束了,下次运行再来取shmp,仍然是hello。重启电脑可以清理掉。下面演示父子进程间的通信,就不用snprintf()了
pid_t pid = fork();
if(pid < 0)
{
perror("fork");
exit(1);
}
if(pid > 0) //父进程
{
while(1)
{
scanf("%s", shmp);//将用户输入写进共享内存中
if(!strcmp(shmp, "quit"))
{//如果是传的是"quit",则退出
break;
}
}
wait(NULL);//等给子进程收尸
}
else //子进程
{
while(1)
{
if(!strcmp(shmp, "quit"))
{
break;
}
if(*shmp)
{
printf("child process read %s\n", shmp);
bzero(shmp, 20);//清理shmp,防止反复打印
}
sleep(1);//用来防止子进程一直在while里高速循环,该方法效率不高,可以用信号量替代
}
}
shmdt(shmp);//关闭共享内存映射关系
return 0;
}