进程通信之共享内存
来源:互联网 发布:share p图软件 编辑:程序博客网 时间:2024/05/23 19:18
–共享内存是进程间通信中最简单的方式之一。共享内存在各种进程间通信方式中具有最高的效率。因为系统内核没有对访问共享内存进行同步,您必须提供自己的同步措施。解决这些问题的常用方法是通过使用信号量进行同步。
2、int shmget(key_t key, size_t size, int shmflg)
–shmget((key_t)1234, sizeof(struct shared_use_st), 0666|IPC_CREAT)
–shmget得到一个共享内存标识符或创建一个共享内存对象
–key:建立新的共享内存对象
–size:新建立的内存大小(以字节为单位)
–shmflg:标识符
例:
#include<sys/types.h>#include<sys/ipc.h>#include<sys/shm.h>#include<stdlib.h>#include<stdio.h>#define BUFSZ 4096int main(void){int shm_id; /*共享内存标识符*/shm_id = shmget(IPC_PRIVTE, BUFSZ,0666);if(shm_id < 0) { /*创建共享内存*/perror("shmgget");exit(1);}printf("successfully created segment :%d\n",shm_id);system("ipcs -m"); /*调用ipcs命令查看IPC*/eixt(0);}$gcc create_shm.c -o create_shm
$./create_shm
successfully created segment :98305
-------shared Memory segments--------
key shemid owner perms bytes nattch status
0x00000000 0 linux-c 600 393216 2 dest
0x00000000 98305 linux-c 666 4096 0
3、将一个存在的共享内存连接到本进程空间
void *shmat(int shmid, const void *shmaddr, int shmflg)
–shmat(shmid, 0, 0)–返回共享的内存地址,否则返回-1
–shmid:共享内存标识符
–shmaddr:指定共享内存出现在进程内存地址的什么位置,直接指定为NULL让内核自己决定一个合适的地址位置
–shmflg SHM_RDONLY:为只读模式,其他为读写模式
addr 和 flag 组合 说明要引入的地址值,通常只有两种用法:
注:如函数成功返回值为实际引入的地址,如失败返回-1。shmat()函数成功执行会将shm_id段的shmid_ds结构的shm_nattch计数器的值加。
4、对共享内存段操作结束时从进程空间中脱离
#include<sys/shm.h>
int shmdt(void *addr);
参数addr是调用shemat()函数的返回值,如函数执行成功返回0,并将该共享内存的shmid_ds结构的shm_nattch计数器减1,如失败返回-1。
例:
#include<sys/types.h>#include<sys/ipc.h>#include<sys/shm.h>#include<stdlib.h>#include<stdio.h>int main(int argc, char *argv[]){int shm_id;char *shm_buf;if(argc != 2) {printf("USAGE: atshm <identifier>");exit(1);}shm_id = atoi(argv[1]);if((shm_buf = shmat(shm_id,0 ,0)) < (char *)0) {perror("shmat");exit(1);}printf("segment attached at %p\n", shm_buf);system("ipc -m");sleep(3);if((shmdt(shm_buf)) < 0) {perror("shmdt");exit(1);}printf("segment detached \n");system("ipcs -m");exit(0);}
$ gcc opr_shm.c -o opr_shm
segment attached at oxb7723000
key shemid owner perms bytes nattch status
0x00000000 0 linux-c 600 393216 2 dest
0x00000000 98305 linux-c 666 4096 1
key shemid owner perms bytes nattch status
0x00000000 0 linux-c 600 393216 2 dest
0x00000000 98305 linux-c 666 4096 0
5、int shmctl(int shmid, int cmd, struct shmid_ds *buf)
–shmctl(shmid, IPC_RMID, 0) == -1
–shmid:共享内存标识符
–cmd IPC_RMID:删除这片共享内存
–buf:共享内存管理结构体
cmd的值 意义
IPC_STAT 取shm_id 所指向内存共享段的shm_ds结构,对参数buf指向的结构赋值。
IPC_SET 使用buf指向的结构对,sh_mid段的相关结构赋值,只对以下几个域有作用。
shm_perm.uid shm_perm.gid shm_perm.mode
注意此命令只有具备以下条件的进程才可以请求:
(1)进程的用户ID等于shm_perm.cuid shm_perm.uid
(2)超级用户特权进程。
IPC_RMID 删除shm_id所指向的共享内存段,只有当shmid_ds结构的shm_nattch 域为0时
才会真正执行删除命令,否则不会删除该段。注意此命令的请求规则与IPC_SET命令相同
SHM_LOCK 锁定共享内存段在内存,此命令只能由超级用户请求。
SHM_UNLOCK 对共享内存段解锁,此命令只能由超级用户请求。
例:
shmdata.h
#ifndef _SHMDATA_H_HEADER #define _SHMDATA_H_HEADER #define TEXT_SZ 2048 struct shared_use_st { //作为一个标志,非0:表示可读,0表示可写int written;//记录写入和读取的文本 char text[TEXT_SZ]; }; #endif
#include <unistd.h> #include <stdlib.h> #include <stdio.h> #include <sys/shm.h> #include "shmdata.h" int main(void) { int running = 1;//程序是否继续运行的标志 void *shm = NULL;//分配的共享内存的原始首地址 struct shared_use_st *shared;//指向shm int shmid;//共享内存标识符 //创建共享内存 shmid = shmget((key_t)1234, sizeof(struct shared_use_st), 0666|IPC_CREAT); if(shmid == -1) { fprintf(stderr, "shmget failed\n"); exit(EXIT_FAILURE); } //将共享内存连接到当前进程的地址空间 shm = shmat(shmid, 0, 0); if(shm == (void*)-1) { fprintf(stderr, "shmat failed\n"); exit(EXIT_FAILURE); } printf("\nMemory attached at %p\n", shm); //设置共享内存 shared = (struct shared_use_st*)shm; shared->written = 0; while(running)//读取共享内存中的数据 { //没有进程向共享内存定数据有数据可读取 if(shared->written != 0) { printf("You wrote: %s", shared->text); sleep(rand() % 3); //读取完数据,设置written使共享内存段可写 shared->written = 0; //输入了end,退出循环(程序) if(strncmp(shared->text, "end", 3) == 0) running = 0; } else//有其他进程在写数据,不能读取数据 sleep(1); } //把共享内存从当前进程中分离 if(shmdt(shm) == -1) { fprintf(stderr, "shmdt failed\n"); exit(EXIT_FAILURE); } //删除共享内存 if(shmctl(shmid, IPC_RMID, 0) == -1) { fprintf(stderr, "shmctl(IPC_RMID) failed\n"); exit(EXIT_FAILURE); } exit(EXIT_SUCCESS); }
shmwrite.h
#include <unistd.h> #include <stdlib.h> #include <stdio.h> #include <string.h> #include <sys/shm.h> #include "shmdata.h" int main(void) { int running = 1; void *shm = NULL; struct shared_use_st *shared = NULL; char buffer[BUFSIZ + 1];//用于保存输入的文本 int shmid; //创建共享内存 shmid = shmget((key_t)1234, sizeof(struct shared_use_st), 0666|IPC_CREAT); if(shmid == -1) { fprintf(stderr, "shmget failed\n"); exit(EXIT_FAILURE); } //将共享内存连接到当前进程的地址空间 shm = shmat(shmid, (void*)0, 0); if(shm == (void*)-1) { fprintf(stderr, "shmat failed\n"); exit(EXIT_FAILURE); } printf("Memory attached at %p\n", shm); //设置共享内存 shared = (struct shared_use_st*)shm; while(running)//向共享内存中写数据 { //数据还没有被读取,则等待数据被读取,不能向共享内存中写入文本 while(shared->written == 1) { sleep(1); printf("Waiting...\n"); } //向共享内存中写入数据 printf("Enter some text: "); fgets(buffer, BUFSIZ, stdin); strncpy(shared->text, buffer, TEXT_SZ); //写完数据,设置written使共享内存段可读 shared->written = 1; //输入了end,退出循环(程序) if(strncmp(buffer, "end", 3) == 0) running = 0; } //把共享内存从当前进程中分离 if(shmdt(shm) == -1) { fprintf(stderr, "shmdt failed\n"); exit(EXIT_FAILURE); } sleep(2); exit(EXIT_SUCCESS); }
- 进程通信之共享内存
- 进程通信之共享内存
- 进程通信之共享内存
- 进程通信之共享内存
- 进程通信之共享内存
- 进程通信之共享内存
- 【进程通信】之共享内存
- 进程通信之共享内存
- 进程通信之共享内存
- 进程通信之共享内存
- linux进程间通信之共享内存
- 进程间通信之共享内存篇
- linux进程间通信之共享内存
- 进程间通信之共享内存
- 进程间通信之共享内存
- 进程间通信之共享内存
- 进程间通信之共享内存篇
- 进程通信之五 共享内存
- 【JVM学习系列】JDK、JRE和JVM的区别
- 可以落地的软件架构
- Thread Class
- pandas库学习记录
- prompt+date.now打字计时器
- 进程通信之共享内存
- Oracle.ManagedDataAccess连接Oracle数据库
- 第二章:数据库的实现 (课后简答题二)
- cygpath
- 从DLL中导出函数
- C++头文件学习
- keil5创建工程
- 编译、运行与java类型转化
- 【工作记录】一串带中文及空格的路径引发的“血案”