进程间通信--共享内存
来源:互联网 发布:淘宝手机怎么退货退款 编辑:程序博客网 时间:2024/06/05 22:38
进程间通信一般分为
¥1 管道:半双工的方式进行通信,而且范围现定于有亲缘关系的进程间使用,比如父子关系。
¥2 有名管道:和管道一样的通信方式,当时可以允许没有亲缘关系的进程进行通信。
¥3 信号量:相当于一种锁机制,防止不同的进程同时对一个对象进行访问。
¥4 消息队列:是消息的链表。
¥5 信号:通知进程某个事件已经发生。
¥6 共享内存:有一个进程创建,多个进程可以访问,本质是映射一段内被其他进程访问的内存,是最常见的IPC通信方式。
¥7 套接字:套接字也是一种进程间通信的方式。
今天要谈的是共享内存的方式:
两个互不相干的正在运行的进程访问同一块逻辑内存,并进行数据传输。
进程可以讲共享内存连接到自己的地址空间中,所有的进程都可以这么做,就好像这块内存就是由malloc分配的原始内存一样,这样就造成了如果某个人进程对其进行写操作,结果将立刻在另一个进程上显示出来。
(共享内存并没有提供同步机制,没法自动产生锁的效果,但是可以通过修好两的方式来达到锁的效果)
共享内存的使用教程
1.相关函数(相关函数参数介绍自己查阅,动动手)
int shmget(key_t key ,size_t size,int shmflg);(创建共享内存)
void *shamat (int shm_id ,const void* shm_addr,int shmflg);(链接共享内存地址到自己的地址空间)
int shmdt(const void *shmaddr)(将内存从被使用的进程中剥离)
int shmctl(int shm_id,iint command,struct shmid_ds *buf);(根据不同的参数来进行)
2.使用中应注意要想让程序安全的执行,就要有一种进程同步机制,保证在进入临界区的操作都是原子操作,例如信号量的操作就是原子操作。
以下是附带的代码,供参考.
两个进程相同的数据结构:
就是读写的功能和写的大小
#ifndef _SHMDATA_H_HEADER#define _SHMDATA_H_HEADER#define TEXT_SZ 2048struct shared_use_st{int written;//作为一个标志,非0:表示可读,0表示可写char text[TEXT_SZ];//记录写入和读取的文本};
读进程:
#include <unistd.h>#include <stdlib.h>#include <stdio.h>#include <sys/shm.h>#include "shmdata.h"int main(){int alive = 1;//程序是否继续运行的标志void *shm = NULL;//分配的共享内存的原始首地址struct shared_use_st *shared;//指向shmint 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);//shmid进程的0地址if(shm == (void*)-1){ fprintf(stderr, "shmat failed\n"); exit(EXIT_FAILURE);}printf("\nMemory attached at %X\n", (int)shm);//设置共享内存shared = (struct shared_use_st*)shm;shared->written = 0;//初始化while(alive)//读取共享内存中的数据{
//没有进程向共享内存写数据此时还有数据可读取if(shared->written != 0){printf("You wrote: %s", shared->text);sleep(rand() % 3);//读取完数据,设置written使共享内存段可写shared->written = 0;//输入了over,退出循环(程序)if(strncmp(shared->text, "over", 3) == 0)alive = 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);}写进程:
#include <unistd.h>#include <stdlib.h>#include <stdio.h>#include <string.h>#include <sys/shm.h>#include "shmdata.h"int main(){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 %X\n", (int)shm);//设置共享内存shared = (struct shared_use_st*)shm;while(alive)//向共享内存中写数据{//数据还没有被读取,则等待数据被读取,不能向共享内存中写入文本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;//输入了over,退出循环(程序)if(strncmp(buffer, "over", 3) == 0)alive = 0;}//把共享内存从当前进程中分离if(shmdt(shm) == -1){fprintf(stderr, "shmdt failed\n");exit(EXIT_FAILURE);}sleep(2);exit(EXIT_SUCCESS);}
操作方式为:gcc -o read read.c
gcc -o write write.c
./write
./read
观察结果,如果愿意把结果附在评论上,可以相互交流。
附:ipcs -m 小工具可以用来查看共享内存的情况。
- 进程间通信-共享内存
- 进程间通信---共享内存
- 进程间通信--共享内存
- 进程间通信--共享内存
- 进程间通信-共享内存
- 进程间通信共享内存
- 进程间通信-共享内存
- 进程间通信---共享内存
- 进程间通信----共享内存
- 【进程间通信】共享内存
- 进程间通信共享内存
- 进程间通信----共享内存
- 进程间通信---共享内存
- 进程间通信--------共享内存
- 进程间通信---共享内存
- 进程间通信-共享内存
- 进程间通信----共享内存
- 进程间通信---共享内存
- 西邮linux兴趣小组2017纳新题知识点总结
- 教你如何将工程中的一个功能模块提取成library库文件,供其他工程轻松接入,只需简单5步
- 路由表条目生成算法
- PHP调用命令无效果以及JAVA安装在普通用户找不到的问题
- Android 通用的ViewHolder和Adapter的打造
- 进程间通信--共享内存
- quartzs每小时执行一次(整点整分)
- 使用drag与drop实现拖拽,(vue)
- 基于MFC的俄罗斯方块小游戏(二)
- C++ Primer Plus, Chapter 13, excercise
- 谈谈龙之谷手游兼容测试的一百个坑
- linux驱动开发之字符设备--自动创建设备节点
- deadline实用功能汇总,财主的粮仓
- android蓝牙电话监听状态