C实现进程间通信(管道; 共享内存,信号量)
最近学习了操作系统的并发;以下是关于进程间实现并发,通信的两个方法。
例子:
求100000个浮点数的和。要求:
(1)随机生成100000个浮点数(父进程)。
(2)然后创建4个后代进程,分别求25000个浮点数的和。
(3)父进程对4个后代进程的结果求和。
(4)每个子进程在屏幕上以格式“(ID_k) Child_k sum: XXX”打印信息,
其中k的取值为1~4,代表子进程的编号,ID_k表示第k个子进程的ID,XXX是该子进程计算的结果。
(5)父进程在屏幕上以格式 “(ID)Parent direct sum:YYY, sum from children: ZZZ”打印信息,
其中ID表示父进程的ID,YYY为直接由100000个随机数求和的值,ZZZ为把4个子进程的结果相加的值。
1:利用管道进行进程间的通信
用到下列函数
pipe() from unistd.h
write(), read()
fork(); //创建子进程
管道只能用于具有亲缘关系的进程,可以将其看作一个文件,但有别于普通的文件, 管道一次只可以被一个进程访问,能实现互斥;
pipe(int fd[] ), 其参数为长度为2的int数组,分别代表读端fd[0], 写端fd[1], 在创建管道后,f d[0],fd[1]成为文件描述符;
写入(write)管道一端fd[1]的数据,在管道的另一端fd[0]可以被进程读取(read);
2:利用共享内存实现通信, 信号量实现互斥
共享内存使用了以下函数:
int shm_open(const char *name, int oflag, mode_t mode); //创建或打开共享内存, 返回文件描述符
int ftruncate(int fd, off_t FILE_SIZE); //调整共享内存空间大小
void*mmap ( void * addr , size_t len , int prot , int flags , int fd , off_t offset ) //将文件映射到进程的地址空间,返回指向地址空间的指针
int munmap(void *start, size_t length); //解除地址映射
int shm_unlink(const char *name); //删除shm_open()创建的共享内存
函数具体用法,可见链接,讲述的很详细了;
具体思路:
一:实现进程间的通信,无非就是各进程间数据的交流,传输;
1、shm_open()函数是创建或打开一个已存在(唯一的name)的共享内存,返回文件描述符,可以看作是创建或打开了一个文件,说法不同而已
2、ftruncate()函数用于指定文件(fd)有多大
3、关键步骤就是mmap(),它将指定的文件(fd)或其他对象映射到内存, 得到可以直接操作的指针对象,不需调用write, read等
4、然后就是在使用完成后需要解除映射munmap(), 和删除创建的共享内存(name)shm_unlink(),; 对于做打开共享内存操作的进程,也需要执行这些操作(1,2,3,4)
二:然后使用信号量实现互斥:
互斥的意思为:当一个进程在临界区访问共享资源时,其他进程不能进入该临界区访问任何共享资源
临界区代表进程将访问共享资源的一段代码
当我们在向共享区写入数据时,显然不想多个进程同时访问,因为会造成不必要的麻烦,就需要信号量来实现这种互斥的机制
sem_t *sem_open(const char *name,int oflag, mode_t mode,unsigned int value) //创建或打开一个存在的(name)信号量
int sem_wait(sem_t *sem) // 使信号量(value)减1,若信号量小于0,则阻塞执行semwait()的进程
临界区代码一般存在于这两个调用之间,比如:当前进程向共享区写数据,如受到sem_wait阻塞,表示资源已经用尽或其他进程正在访问,需等待
int sem_post(sem_t *sem) // 当前进程离开临界区时,使信号量(value)加1,
int sem_unlink(count char *name) //删除信号量
函数具体用法,可见链接,讲述的很详细了;
需要注意的是:
1:在使用共享内存和信号量时要注意,有些调用是使用的共享内存和信号量的name, 但有些是使用的创建或打开他们的返回值(fd和sem_t*)
2:如在子进程创建之前,父进程已创建了共享内存或信号量,则子进程无需在进行打开操作,可直接使用
C实现进程间通信(管道; 共享内存,信号量)的更多相关文章
- Linux环境进程间通信(五): 共享内存(下)
linux下进程间通信的几种主要手段: 管道(Pipe)及有名管道(named pipe):管道可用于具有亲缘关系进程间的通信,有名管道克服了管道没有名字的限制,因此,除具有管道所具有的功能外,它还允 ...
- Linux环境进程间通信(五): 共享内存(上)
linux下进程间通信的几种主要手段: 管道(Pipe)及有名管道(named pipe):管道可用于具有亲缘关系进程间的通信,有名管道克服了管道没有名字的限制,因此,除具有管道所具有的功能外,它还允 ...
- Linux进程IPC浅析[进程间通信SystemV共享内存]
Linux进程IPC浅析[进程间通信SystemV共享内存] 共享内存概念,概述 共享内存的相关函数 共享内存概念,概述: 共享内存区域是被多个进程共享的一部分物理内存 多个进程都可把该共享内存映射到 ...
- Linux进程间通信—使用共享内存
Linux进程间通信-使用共享内存 转自: https://blog.csdn.net/ljianhui/article/details/10253345 下面将讲解进程间通信的另一种方式,使用共享内 ...
- 浅析Linux下进程间通信:共享内存
浅析Linux下进程间通信:共享内存 共享内存允许两个或多个进程共享一给定的存储区.因为数据不需要在客户进程和服务器进程之间复制,所以它是最快的一种IPC.使用共享内存要注意的是,多个进程之间对一给定 ...
- 进程间通信机制(管道、信号、共享内存/信号量/消息队列)、线程间通信机制(互斥锁、条件变量、posix匿名信号量)
注:本分类下文章大多整理自<深入分析linux内核源代码>一书,另有参考其他一些资料如<linux内核完全剖析>.<linux c 编程一站式学习>等,只是为了更好 ...
- Linux进程间通信 共享内存+信号量+简单样例
每个进程都有着自己独立的地址空间,比方程序之前申请了一块内存.当调用fork函数之后.父进程和子进程所使用的是不同的内存. 因此进程间的通信,不像线程间通信那么简单.可是共享内存编程接口能够让一个进程 ...
- Linux进程间通信——使用共享内存
一.什么是共享内存 顾名思义,共享内存就是允许两个不相关的进程访问同一个逻辑内存.共享内存是在两个正在运行的进程之间共享和传递数据的一种非常有效的方式.不同进程之间共享的内存通常安排为同一段物理内存. ...
- Linux进程间通信——使用共享内存(转)
一.什么是共享内存 顾名思义,共享内存就是允许两个不相关的进程访问同一个逻辑内存.共享内存是在两个正在运行的进程之间共享和传递数据的一种非常有效的方式.不同进程之间共享的内存通常安排为同一段物理内存. ...
- Linux进程间通信(四) - 共享内存
共享内存的优势 采用共享内存通信的一个显而易见的好处是效率高,因为进程可以直接读写内存,而不需要任何数据的拷贝.对于像管道和消息队列等通信方式,则需要在内核和用户空间进行四次的数据拷贝,而共享内存则只 ...
随机推荐
- golang之method
method Go does not have classes. However, you can define methods on types. package main import ( &qu ...
- P2764 最小路径覆盖问题 网络流重温
P2764 最小路径覆盖问题 这个题目之前第一次做的时候感觉很难,现在好多了,主要是二分图定理不太记得了,二分图定理 知道这个之后就很好写了,首先我们对每一个点进行拆点,拆完点之后就是跑最大流,求出最 ...
- P2762 太空飞行计划问题 网络流
题目描述 W 教授正在为国家航天中心计划一系列的太空飞行.每次太空飞行可进行一系列商业性实验而获取利润.现已确定了一个可供选择的实验集合E={E1,E2,…,Em},和进行这些实验需要使用的全部仪器的 ...
- React Native超简单完整示例-tabs、页面导航、热更新、用户行为分析
初学React Native,如果没有人指引,会发现好多东西无从下手,但当有人指引后,会发现其实很简单.这也是本人写这篇博客的主要原因,希望能帮到初学者. 本文不会介绍如何搭建开发环境,如果你还没有搭 ...
- python学习之if条件句的使用
if循环 if 条件: 代码块 运行 if else的用法 if elseif else用法 if 条件1: elif 条件2: elif条件3: else:
- 02_互联网基本原理和HTML入门
上节课的知识复习 互联网的原理:服务器.浏览器.HTTP.知道网页文件是真实的物理存在,用HTTP请求这个文件. 要知道网址的含义:http://www.iqianduan.cn/aaa 请求哪个文件 ...
- 用Visual Studio2019自定义项目模板
项目模板简介 众所周知,在我们使用VS新建项目时,都需要选择一个项目模板,如下图: 我们选择完项目模板进行创建,创建完成之后,可以发现项目中已经包含了一些基础的文件.例如MVC: 可以看到,MVC项目 ...
- 【Hadoop离线基础总结】Hadoop的架构模型
Hadoop的架构模型 1.x的版本架构模型介绍 架构图 HDFS分布式文件存储系统(典型的主从架构) NameNode:集群当中的主节点,主要用于维护集群当中的元数据信息,以及接受用户的请求,处理用 ...
- Vular开发手记#1:设计并实现一个拼插式应用程序框架
可视化编(rxeditor)辑告一段落,在知乎上发了一个问题,询问前景,虽然看好的不多,但是关注度还是有的,目前为止积累了21w流量,因为这个事,开心了好长一段时间.这一个月的时间,主要在设计制作Vu ...
- spring源码解析--上
本文是作者原创,版权归作者所有.若要转载,请注明出处. 首先是配置类 package com.lusai.config; import org.springframework.context.anno ...