基于Linux内核的共享内存C语言示例

时间:2024-03-18 15:15:15
#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; }