当前位置: 首页 > 编程日记 > 正文

关于进程间通信的学习心得

进程:进程是指独立地址空间的指令序列

进程的五种状态:新建,就绪,运行,睡眠,僵死

进程间通信:是不同进程之间进行一些"接触",这种接触有简单,有复杂。机制不同,复杂度也不同。通信是一个广义上的意义,不仅指大批量数据传送,还包括控制信息的传送,但使用方法是基本相同的。

基本的进程通信机制

1.传统UNIX-IPC机制:信号和管道

2.SystemVIPC机制:共享内存、信号量和消息队列

3.起源于Unix BSD版本的套结字(Socket

4.远程过程调用(RPC

信号:Unix系统中使用的最古老的进程间通讯的方法之一,用于向一个或多个进程发送异步事件的信号。信号可以类比于DOS下的INT或者是Windows下的事件。在有一个信号发生的时候,相应的信号就会发送给相应的进程。

信号机制的实现

1.信号包括待处理信号和被阻塞信号

2.如果产生了一个被阻塞的信号,它一直保留待处理,直到被解除阻塞。

3.系统保存每一个进程如何处理每一种可能的信号的信息。

4.系统判断进程是希望忽略这个信号还是让内核处理。进程通过执行系统调用改变缺省的信号处理。

对信号的处理

1.初始化信号集,只有在信号集里面的信号才会被考虑

2.安装信号处理器。所谓信号处理器,就是指定了一些对信号的处理方法。在安装的时候,一定要对特定的信号赋予正确的信号处理函数。

信号相关函数

int sigaction(int signo, const struct sigaction *act, struct sigaction *oact);为进程安装信号处理器,struct sigaction数据结构是用来保存信号处理器的相关信息。

int sigemptyset(sigset_t *set);将信号集合清空。

int sigfillset(sigset_t *set);将信号集合设置成包含所有的信号,在对信号进行操作以前一定要对信号集进行初始化。

int sigaddset(sigset_t *set, int signo);向信号集中加入signo对应的新信号。

int sigdelset(sigset_t *set, int signo);从信号集中删除signo对应的一个信号。

int sigismember(const sigset_t *set, int signo);判断某个信号是否在信号集中。

int sigprocmask(int how,const sigset_t *set, sigset_t *oset);设置进程的信号屏蔽码。信号屏蔽码可以用来在某段时间内阻塞一些信号集中的信号。

管道通信:是最古老的Unix IPC工具,一个进程从管道一头写数据,另一个进程从管道另一头读数据,以实现它们之间通信的共享方式,又称pipe文件。由于发送和接收都是利用管道进行通信的,故称为管道通信。通信方式是单向的。管道类型分为:无名管道、命名管道

管道通信的思想

1.发送进程可以源源不断的从pipe一端写入数据流,在规定的pipe文件的最大长度(如4096字节)范围内,每次写入的信息长度是可变的。

2.接收进程在需要时可以从pipe的另一端读出数据,读出单位长度也是可变的。

基本管道调用函数

int do_pipe(int *fd);创建管道

static int pipe_release(struct inode *inode, int decr, int decw);管道释放

无名管道II

显示了每一个file数据结构包含了不同的文件操作例程的向量表的指针:一个用于写,另一个从管道中读。这掩盖了和通用的读写普通文件的系统调用的不同。当写进程向管道中写的时候,字节拷贝到了共享的数据页,当从管道中读的时候,字节从共享页中拷贝出来。

命名管道:又名FIFO,它不是临时的对象,而是文件系统中的实体,可以用mkfifo命令创建。系统必须处理在写进程打开FIFO之前打开FIFO读的进程,以及在写进程写数据之前读的进程。它使用和无名管道一样的数据结构和操作。

       (写入端)[Fd1]pipe(fd)[Fd0](读出端)

信号量:信号量(Semaphore)和信号是不同的东西,信号是实现约定的固定的值,而信号量是一个变量记录着某些特定信息,它的使用主要是用来保护共享资源,使得该资源在一个时刻只让一个进程拥有。

信号量的数据结构:使用semid_ds数据结构表达信号量。系统中所有的semid_ds数据结构都由semary指针向量表指向。每一个信号灯数组中都有sem_nsems,通过sem_base指向的一个sem数据结构来描述

信号量机制的实现

1.对信号量的操作只有两个:PV

2.为了在逻辑上便于组织信号量,信号量机制中有一个概念是信号量组。我们在一个信号量组中创建相关的信号量,这样逻辑上清晰也便于管理。

3.在使用之前同样需要对他们进行初始化:生成或打开信号量组,向其中生成或删除指定的信号量。

4.一个信号量必须属于一个信号量组,否则不能被系统所使用。

5.信号量和信号量组是不会被系统所自动清理的,所以在进程退出前,需要及时清理生成的那些信号量。

信号量的相关函数

int semget(key_t key, int nsems, int semflg);创建一个新的信号量组或获取一个已经存在的信号量组。

int semop(int semid, struct sembuf *sop, int nsops);一次对一个或多个信号量进行操作,用于PV操作。

Int semctl(int sem_id, int semnum, int cmd, union semun arg);用来获取一些信号量的使用信息或者是来对信号量进行控制。

共享内存

    共享内存是进程通信的一个重要方法,为进程提供了直接通信的手段。操作系统中一个或多个进程通过同时出现在它们的虚拟地址空间的内存通讯,该虚拟内存被每个共享进程的页表所引用,它们的地址无需相同。进程对共享内存的访问是受控的,信号量等机制实现了共享内存访问的同步

共享内存的简单原理

每一个新创建的内存区域都用一个shmid_ds数据结构来表达。这些数据结构保存在shm_segs向量表中。Shmid_ds数据结构描述了这个共享内存取有多大、多少个进程在使用它以及共享内存如何映射到它们的地址空间。由共享内存的创建者来控制对于这块内存的访问权限和它的key是公开或私有。如果有足够的权限它也可以把共享内存锁定在物理内存中。每一个希望共享这块内存的进程必须通过系统调用粘附(attach)到虚拟内存。这为该进程创建了一个新的描述这块共享内存的vm_area_struct数据结构。进程可以选择共享内存在它的虚拟地址空间的位置或者由Linux选择一块足够的的空闲区域。这个新的vm_area_struct结构放在由shmid_ds指向的vm_area_struct列表中。通过vm_next_sharedvm_prev_shared把它们连在一起。

共享内存的基本函数

int shmget(key_t key,int size,int shmflg);建立新的共享内存或一个已存在的共享内存描述字

void *shmat(int shmid,const void *shmaddr,int shmflg);将物理共享内存粘附到进程虚拟地址空间

int shmdt(const void *shmaddr);进程从其虚拟地址空间分离共享内存

int shmctl(int shmid,int cmd,struct shmid_ds *buf);查询及设置一个共享内存

共享内存机制的实现

在使用一个共享内存之前我们调用shmat得到共享内存的开始地址,使用结束以后我们使用

shmdt断开这个内存。

进程通过系统调用粘附到虚拟内存,即创建了一个新的描述这块共享内存的vm_area_struct数据结构,这个新的vm_area_struct结构放在由shmid_ds指向的vm_area_struct列表中。通过vm_next_sharedvm_prev_shared把它们连在一起。

虚拟内存在粘附的时候其实并没有创建,而发生在第一个进程试图访问它的时候。

第一个访问共享内存页的进程使得这一页被创建,而随后访问的其他进程使得此页被加到它们的虚拟地址空间。

当进程不再需要共享虚拟内存的时候,它们从中分离出来。只要仍旧有其他进程在使用这块内存,这种分离只是影响当前的进程。

当共享这块内存的最后一个进程从中分离出的时候,共享内存当前在物理内存中的页被释放


消息队列:消息队列是比较高级的一种进程间通信方法,实现一个或多个进程间message传送,一个消息队列可以被多个进程所共享(IPC就是在这个基础上进行的);如果一个进程的消息太多一个消息队列放不下,也可以用多于一个的消息队列(不过可能管理会比较复杂)。

消息队列的基本函数

int msgget(key_t key, int msgflg);获取一个存在的消息队列的ID,或者是根据跟定的权限创建一个消息队列。

int msgctl(int msqid, int cmd, struct msqid_ds *buf);用来从msqid_ds中获取很多消息队列本身的信息。

int msgsnd(int msqid, void *msgp, size_t msgsz, int msgflg);用于向队列发送消息。

int msgrcv(int msqid, void *msgp, size_t msgsz, long int msgtyp, intmsgflg);从队列中接收消息。

消息队列的实现机制

消息队列,是一个队列的结构,队列里面的内容由用户进程自己定义。实际上,队列里面记录的是指向用户自定义结构的指针和结构的大小。要使用message queue,首先要通过系统调用(msgget)产生一个队列,然后,进程可以用msgsnd发送消息到这个队列,消息就是如上所说的结构。别的进程用msgrcv读取。消息队列一旦产生,除非明确的删除(某个有权限的进程或者用ipcrm命令)或者系统重启。否则,产生的队列会一直保留在系统中。而且,只要有权限,就可以对队列进行操作。消息队列和管道很相似,实际上,管道就是用户消息为1个字节的队列。

消息队列的写进程

每一次一个进程试图向写队列写消息,它的有效用户和组的标识符就要和队列的ipc_perm数据结构的模式比较。如果进程可以想这个队列写,则消息会从进程的地址空间写到msg数据结构,放到消息队列的最后。每一个消息都带有进程间约定的,应用程序指定类型的标记。

消息队列的读进程

从队列中读是一个相似的过程。进程的访问权限一样被检查。一个读进程可以选择是不管消息的类型从队列中读取第一条消息还是选择特殊类型的消息。如果没有符合条件的消息,读进程会被加到消息队列的读等待进程,然后运行调度程序。当一个新的消息写到队列的时候,这个进程会被唤醒,继续运行。

消息队列的简单流程

发送进程                             接收流程

Send(m)                              Receive(m )

   Begin                                 begin

   向系统申请一个消息缓冲区              P(SM) 等待接的消息的个数

   P(mutex) 使用公用缓冲区               P(mutex) 使用公用缓冲区

   将发送区消息m送入新申请的消息缓冲区  摘下消息队列中的消息m

   把消息缓冲区挂入接收进程的消息队列     将消息队列m从缓冲区复制到接收区

   V(mutex)释放缓冲区                    释放缓冲区

   V(SM)向接收进程发送消息              V(mutex) 释放公用缓冲区

  End                                     end

Socket

独立于具体协议的网络编程接口;

ISO模型中,主要位于会话层和传输层。

网络编程接口:UNIX BSD的套接字(socket)、UNIX System VTLI

BSD Socket(伯克立套接字)是通过标准的UNIX文件描述符和其它程序通讯的一个方法,目前已经被广泛移植到各个平台。

Socket的类型

流式套接字:提供了一个面向连接,可靠的数据传输服务,数据无差错,无重复地发送且按发送顺序接收.内设流量控制,避免数据流超限;数据被看作是字节流,无长度限制,FTP即用此

数据报套接字:提供了一个无连接服务.数据包以独立包形式被发送,不提供无差错保证,数据可能丢失或重复,并且接受顺序无序,网络文件系统NFS

原始套接字(SOCK_RAW):该接口允许对较低层次协议,如IP,ICMP直接访问

基本套接字调用

创建套接字               socket()

绑定本机端口           bind()

建立连接                   connect()

接受连接                   accept()

监听端口                   listen()

数据传输                   send(), recv()

关闭套接字               close();

Socket相关数据结构

struct sockaddr_in

          {

                  short int        sin_family;    /*通信类型*/

                  unsigned short int  sin_port;       /*端口号,网络直接顺序*/

                  struct in_addr  

         }


相关文章:

Go modules基础精进,六大核心概念全解析(上)

Go 语言做开发时,路径是如何定义的?Go Mudules又为此带来了哪些改变?本文将会全面介绍Go Modules六大核心概念,包括了设计理念与兼容性原则等,掌握这些技术点对于管理和维护Go 模块有重要价值。 在Go Modules 的前世今…

PARAMETERS 指令

语法: PARAMETERS <p> [DEFAULT <f>] [LOWER CASE] [OBLIGATORY] [AS CHECKBOX] [RADIOBUTTON GROUP <rad>] 实例: PARAMETERS: NAME(8), AGE TYPE I, BIRTH TYPE D. OBLIGATORY:强制要求输入, 屏幕上会出現一个“√” , 使用者必须要输入才可。 AS C…

阿里发布AliGenie2.0系统,“百箱大战”用上视觉武器

天猫精灵X1的升级版X2没有预期出现&#xff0c;而人机交互系统AliGenie升级到最新的2.0版本&#xff0c;功能强大。 3月22日&#xff0c;阿里巴巴人工智能实验室总经理浅雪&#xff08;陈丽娟&#xff09;发布AliGenie2.0系统&#xff0c;它最大的改进是在1.0的基础上增加了视觉…

Centos5.6 VNC安装配置【无错版】

不严格按本步骤就会出现VNC桌面花屏&#xff0c;就是桌面分离为一层一层的。。。 ---------------------------------------- 先装X window http://blog.csdn.net/21aspnet/article/details/6997549 ---------------------------------------- Centos5.6 VNC安装配置 一、检查是…

关于IOS的屏幕适配(iPhone)——资源适配

IOS的屏幕适配几乎不需要大量的代码操作&#xff0c;更多的时间我们只是动动鼠标选择一下就搞定。可以苹果在这方面做的还是比较人性的&#xff0c;解放了开发者。 首先来说说Iphone这几种屏&#xff08;由于最近做的是iPhone APP还未涉及到iPad&#xff0c;将来涉及到iPad时会…

Go modules基础精进,六大核心概念全解析(下)

Go 语言做开发时&#xff0c;路径是如何定义的&#xff1f;Go Mudules又为此带来了哪些改变&#xff1f;本文将会全面介绍Go Modules六大核心概念&#xff0c;包括了设计理念与兼容性原则等&#xff0c;掌握这些技术点对于管理和维护Go 模块有重要价值。 在上篇中&#xff0c;我…

京东区块链白皮书解读, 做“链接器”,一次技术宣言

前天&#xff0c;京东对外发布了《京东区块链技术白皮书(2018)》。 昨天&#xff0c;京东金融发布了旨在帮助中小银行提升零售信贷效率的产品“北斗”。目前&#xff0c;“北斗”已经接入包括江苏银行、南京银行、包商银行在内的近30家银行。京东金融还与近30家商业银行共同发起…

xauth: (stdin):1: bad display name LSPPC-Lenny:1 in add command

启动vnc4server之后出现如下错误提示&#xff1a;LSPPC-Lenny:~# vnc4serverxauth: (stdin):1: bad display name "LSPPC-Lenny:1" in "add" command New ‘LSPPC-Lenny:1 (root)’ desktop is LSPPC-Lenny:1 Starting applications specified in /root/…

使用 Python 和 OpenCV 构建 SET 求解器

作者 | 小白来源 | 小白学视觉小伙伴们玩过 SET 吗&#xff1f;SET 是一种游戏&#xff0c;玩家在指定的时间竞相识别出十二张独特纸牌中的三张纸牌&#xff08;或 SET&#xff09;的模式。每张 SET 卡都有四个属性&#xff1a;形状、阴影/填充、颜色和计数。下面是一个带有一些…

Delphi XE5 常用功具与下载

1.Delphi XE5 正式版http://altd.embarcadero.com/download/radstudio/xe5/delphicbuilder_xe5_win.isohttp://altd.embarcadero.com/download/radstudio/xe5/delphicbuilder_xe5_upd1_win.iso2. cnpack 助手工具http://www.cnpack.org/download/unstable/CnWizards_1.0.1.665_…

maven学习(4)-Maven 构建Web 项目

紧接着上一节(3)&#xff0c;现在maven新建web项目&#xff0c;user-web。模拟一个用户登录的需求&#xff1a; 工程结构&#xff1a; pom.xml: <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance&qu…

如何查看linux版本

1. 查看内核版本命令&#xff1a; 1) [rootq1test01 ~]# cat /proc/version Linux version 2.6.9-22.ELsmp (bhcompilecrowe.devel.redhat.com) (gcc version 3.4.4 20050721 (Red Hat 3.4.4-2)) #1 SMP Mon Sep 19 18:00:54 EDT 2005 2) [rootq1test01 ~]# uname -a …

存储过程由结构表生成表

结构表 CREATE TABLE JGTB5001( ZDM VARCHAR2(30 BYTE), HZM VARCHAR2(100 BYTE), LX VARCHAR2(50 BYTE), JD VARCHAR2(20 BYTE), WBKLX VARCHAR2(100 BYTE), FUNCTIONNAME VARCHAR2(50 BYTE), FUNCTIONPARAMETER VARCHAR2(50 BYTE)); 生成的TB表CREATE OR REPLACE PROCEDURE P…

好礼相送|CSDN云原生 Meetup 成都站报名热烈启动,12.18见!

伴随着容器、Kubernetes及微服务等技术热度的持续攀升&#xff0c;云原生正以不可撼动之势&#xff0c;剑指云计算的下一个十年。12月18日&#xff0c;CSDN将在成都举办第三场云原生线下Meetup。在这里&#xff0c;您可以了解各大领先企业的云原生落地实践&#xff0c;与众多云…

vue-music 音乐网站

在学习完vueJS,一直想做个项目来锻炼一下,选来选去&#xff0c;还是做个网易云音乐&#xff0c;其间遇到了很多坑,也逐渐接受了vue这种组件化的思想以及从Dom操作转换为用数据去驱动视图。并且在某部分基础组件上借鉴(搬运)了elementUI的源码(不过elementUI写的是真好) 技术栈 …

shell环境变量

shell环境变量 环境变量 还记得上一章里面﹐我曾经提到过﹕当我们登入系统的时候﹐首先就获得一 shell﹐而且它也占据一个行程&#xff08;进程&#xff09;﹐然后再输入的命令都属于这个 shell 的子程序&#xff08;子进程&#xff09;。如果您学习够细心﹐不难发现我们的 sh…

apache用户认证

先创建一个“用户认证”目录&#xff08;设为abc&#xff09;[rootLAMPLINUX ~]# cd /data/www[rootLAMPLINUX www]# mkdir abc进入abc目录[rootLAMPLINUX www]# cd abc拷贝一个文件&#xff08;作用&#xff1a;验证配置是否生效&#xff09;[rootLAMPLINUX abc]# cp /etc/pas…

20个经典函数细说 Pandas 中的数据读取与存储,强烈建议收藏

作者 | 俊欣来源 | 关于数据分析与可视化大家好&#xff0c;今天小编来为大家介绍几个Pandas读取数据以及保存数据的方法&#xff0c;毕竟我们很多时候需要读取各种形式的数据&#xff0c;以及将我们需要将所做的统计分析保存成特定的格式。我们大致会说到的方法有&#xff1a;…

fastlane自动打包--详细介绍

fastlane--Packaging 自动化打包&#xff0c;通过fastlane自动发布Fastlane安装不在这里详细罗列&#xff0c;参照一下链接流程 https://www.jianshu.com/p/0a113f754c09操作步骤 1.检查Fastlane是否正确安装。输入以下命令&#xff1a; fastlane --version 复制代码可以看到Fa…

【Big Data】HADOOP集群的配置(一)

Hadoop集群的配置&#xff08;一&#xff09; 摘要: hadoop集群配置系列文档&#xff0c;是笔者在实验室真机环境实验后整理而得。以便随后工作所需&#xff0c;做以知识整理&#xff0c;另则与博客园朋友分享实验成果&#xff0c;因为笔者在学习初期&#xff0c;也遇到不少问题…

C语言 条件编译详解

预处理过程扫描源代码&#xff0c;对其进行初步的转换&#xff0c;产生新的源代码提供给编译器。可见预处理过程先于编译器对源代码进行处理。在C 语言中&#xff0c;并没有任何内在的机制来完成如下一些功能&#xff1a;在编译时包含其他源文件、定义宏、根据条件决定编译时是…

凝聚406万开发者 飞桨十大发布提速产业智能化

12月12日&#xff0c;由深度学习技术及应用国家工程实验室主办的WAVE SUMMIT2021深度学习开发者峰会在上海召开。百度首席技术官、深度学习技术及应用国家工程实验室主任王海峰公布飞桨最新成绩单&#xff1a;凝聚406万开发者、创建47.6万模型、服务15.7万企事业单位&#xff0…

环境变量,cp,mv,查看文档命令

2019独角兽企业重金招聘Python工程师标准>>> 一、环境变量PATH echo $PATH 打印当前的环境变量 PATH$PATH:路径 自定义环境变量 which查找某个命令的绝对路径&#xff0c;也可以查看某个命令的别名&#xff0c;which查找的范围就在PATH下的几个目录下查找&#xff1…

Linux中errno使用

当linux中的C api函数发生异常时,一般会将errno变量(需include errno.h)赋一个整数值,不同的值表示不同的含义,可以通过查看该值推测出错的原因&#xff0c;在实际编程中用这一招解决了不少原本看来莫名其妙的问题。但是errno是一个数字&#xff0c;代表的具体含义还要到errno.…

工程师文化:BAT 为什么不喊老板

BAT员工之间不喊老板&#xff0c;也不喊真名&#xff0c;而是用同学、花名&#xff0c;这是虚情假意&#xff1f;还是弘扬武侠文化&#xff1f;还是另有隐情&#xff1f;为什么欧美公司不这么做&#xff1f;本文将带大家走进科学&#xff0c;探索真相。 BAT 的称呼方式 腾讯&am…

SVN常见问题

2019独角兽企业重金招聘Python工程师标准>>> 目录[隐藏] 1. 提示SVN证书过期&#xff1f; 2. 用户名密码校验失败&#xff1f; 3. SVN提交文件时提示文件冲突怎么办&#xff1f; 4. SVN提交文件时提示失败&#xff1f; 1. 提示SVN证书过期&#xff1f; 问题描述&…

2017海克斯康拉斯维加斯美国大会 精彩即将开始

海克斯康集团与遍及全球行业用户的故事已经证明&#xff0c;海克斯康先进的解决方案影响着世界各行各业的发展&#xff0c;并为他们带来了颠覆性的科技变革...... 通过海克斯康集团与遍及全球行业用户的故事&#xff0c;已经证明海克斯康先进的解决方案影响着世界各行各业的发展…

Linux环境编程--waitpid与fork与execlp

waitpidwaitpid(等待子进程中断或结束)表头文件#include<sys/types.h>#include<sys/wait.h>定义函数 pid_t waitpid(pid_t pid,int * status,int options);函数说明waitpid()会暂时停止目前进程的执行,直到有信号来到或子进程结束。如果在调用 wait()时子进程已经结…

C# 批处理制作静默安装程序包

使用批处理WinRAR制作静默安装程序包 echo 安装完窗口会自动关闭&#xff01;&#xff01;&#xff01; echo off start /wait Lync.exe /Install /Silent start /wait vcredist_x86/vcredist_x86.exe /q /norestart start /wait DotNetFx40/dotNetFx40_Full_x86_x64.exe /q /…

程序员是复制粘贴的工具人?还是掌握“谜底”的魔术师?

作者 | David Heinemeier Hansson译者 | 弯月出品 | CSDN&#xff08;ID&#xff1a;CSDNnews&#xff09;编程世界在经历了“Imposter Syndrome(冒充者症候群/负担症候群&#xff09;”和“gatekeeping&#xff08;守门人理论&#xff09;”两方的激战之后&#xff0c;最终以“…