UnixC——进程间通信(IPC)

一、进程间通信(IPC):Unix / Linux 系统基于多进程,进程和进程之间数据的交互。

1.常见的IPC:1)文件    2)信号    3)管道(FIFO)    4)共享内存    5)消息队列  
 6)信号量集    7)网络编程(socket)

2.共享内存、消息队列和信号量集遵循相同的规范,统称为 XSI IPC。

------------------------------------------

二、管道:一种仅做为交互媒介的IPC的特殊的文件,不存储任何的数据,文件名后缀.p,只有在有读且有写操作时才能畅通,否则阻塞。

1.管道有两种用法:有名管道和无名管道。

1)有名管道:可用于所有进程之间的交互。无名管道:只能用于fork()创建的父子进程之间的交互。

2)有名管道:程序员创建管道文件进行IPC。无名管道:系统创建和维护管道文件进行IPC。

2.使用有名管道的步骤:

a.创建管道文件:mkfifo命令|||mkfifo("...")函数 【touch 命令和 open()函数都无法创建管道文件】。

b.像读写普通文件一样操作管道文件。

c.可以删除管道文件。

注意:open 一个管道文件,权限不要用 O_RDWR。

------------------------------------------

三、XSI IPC 的通用规范:每个 IPC 都由一个内部的ID做唯一的标识。内部ID的获取,需要借助与之对应外部key(类型 key_t)。

1. key 获取的三种方式:

a 使用宏 IPC_PRIVATE 做 key,但外部无法获取,基本不用。

b 使用ftok()获取一个 key。

   c 在头文件中为每个IPC统一分配唯一的 key。

2.通过key 获取内部 id:msgget(2)、semget(2)、shmget(2)  //int msgget(key_t key, int msgflg);

3.每种IPC 结构都提供了一个 xxxctl()函数(查询、修改和删除)。

4.所有IPC 结构都是内核管理,不使用时需要手工删除。

5.IPC 结构的相关命令:

ipcs  - 查询当前的 IPC 结构

ipcrm - 删除当前的 IPC 结构 (用 id 删除)

选项:-a 所有 IPC 结构

-m 共享内存  Shared Memory Segments

-q 消息队列  Semaphore Arrays(更常用)

-s 信号量集  Message Queues

------------------------------------------

四、共享内存:以一块共享的物理内存做媒介。共享内存虽然速度最快(效率最高的IPC),但当多个进程同时写数据时,数据会互相覆盖,导致混乱。

1.共享的实现(通常情况下,两个进程无法直接映射相同的内存。):

a)内核先拿出一块物理内存,内核 负责管理。

b)允许所有进程对这块内存进行映射。则两个不同的进程,就可以映射到相同的物理内存上,从而实现信息的交互。

2.编程步骤:

a)获取 key。

b)使用 shmget()函数用key创建 / 获取内部的 ID。

c)使用 shmat()挂接共享内存(映射)- shm_nattch;  /* No. of current attaches */可以像正常操作一样使用共享内存。

d)使用 shmdt()脱接共享内存(解除映射)。

e)如果确定已经不再使用,可以使用shmctl()删除共享内存。

3.相关函数:

1)获取key:key_t ftok(const char *pathname, int proj_id);/* ftok()函数使用给定的文件名(必须存在,可访问的文件)和proj_id的低8位(必须非零)来生成key_t类型System
V IPC的key,适用于msgget(2), semget(2)或者shmget(2)。*/

2)获取(创建)内部ID,并设置共享内存大小:int/*ID */ shmget(key_t key, size_t size/*共享内存的大小*/,
int shmflg/*flag获取时:0;新建时:IPC_CREAT|0666(权限)*/);

3)挂载内存:void *shmat(int shmid, const void *shmaddr, int shmflg);(和mmap相似)如:void *shmat(int shmid, 0, 0);/*If  shmaddr  is NULL, the system chooses a suitable (unused) address at which to attach the
segment. */ /* Return:On success shmat() returns the address of the  attached  shared  memory segment; on error (void *) -1 is returned。*/

4)脱接内存:int shmdt(const void *shmaddr);//shmaddr 是shmat()的返回值,首地址(虚拟)。

5)查询、修改和删除共享内存:int shmctl(int shmid, int cmd, struct shmid_ds *buf /*结构体指针*/ );

cmd 参数:1)IPC_STAT - 查询  2)IPC_SET  - 修改  3)IPC_RMID - 按ID 删除IPC 结构

查询时:会把共享内存的信息放入第三个参数。

修改时:只有用户id、组id和权限可以修改,大小不可修改。

删除时:第三个参数给 0 即可。删除共享内存时,挂接数必须为 0 ,才能真正删除,否则删除只是做一个标记,等挂接数为 0 时,才能真正删除。

------------------------------------------

五、消息队列(FIFO):存放消息的队列。

1.消息队列实现:数据先封入消息中,然后再把消息存入队列。一般情况下,队列有满有空。可以解决多个进程同时写数据的问题。

2.编程步骤:

a)得到外部的 key。

b)使用msgget()函数用key 创建 / 获取一个消息队列ID。

c)把数据 / 消息 存入队列 或 从队列中取出。//函数msgsnd()存入 / msgrcv()取出/*
IPC_NOWAIT 无等待,直接返回 */

d)如果不再使用消息队列,可以msgctl()删除。

3.相关函数:

int msgsnd(int msqid/*消息队列的ID*/, const void *msgp, size_t msgsz, int msgflg); 

a)msgp:消息的首地址,其中消息分为有类型消息(更规范)和无类型消息。

b)有类型消息结构:

struct Msg{ // 结构的命令可以自定义

long mtype;//消息的类型,必须大于 0/*可通过定义宏的方式*/,接收消息时,可以按照类型有选择的接受消息

... ...    //数据区域,可以任意写

}

c)size:是数据区域的大小,不包括 mtype的大小(有些时候也包括,规范情况下,不包括)。

d)flag:选项,可以是 0 代表阻塞(队列满了),也可以是IPC_NOWAIT 代表非阻塞(队列满了直接返回错误)。

e)成功返回 0,失败返回 -1。

ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);

a)msgtyp 可以让接收者有选择的接收消息,值可能是:

0 - 接收任意类型的消息(第一个,先入先出)。

>0 - 接收类型为 mtype 的特定消息。

<0 - 接收类型 小于等于 mtype 绝对值的消息,从小到大接收。

b)成功返回接收到的数据大小,失败返回 -1。

UnixC——进程间通信(IPC),布布扣,bubuko.com

时间: 2024-10-12 13:02:44

UnixC——进程间通信(IPC)的相关文章

Android中进程间通信(IPC)方式总结

IPC为进程间通信或跨进程通信,是指两个进程进行进程间通信的过程.在PC和移动设备上一个进程指的是一个程序或者一个应用,所以我们可以将进程间通信简单理解为不同应用之间的通信,当然这种说法并不严谨. 在Android中,为每一个应用程序都分配了一个独立的虚拟机,或者说每个进程都分配一个独立的虚拟机,不同虚拟机在内存分配上有不同的地址空间,这就导致在不同的虚拟机互相访问数据需要借助其他手段.下面分别介绍一下在Android中进行实现IPC的方式. 1.使用Bundle 我们知道在Android中三大

[原创]chromium源码阅读-进程间通信IPC.消息的接收与应答

chromium源码阅读-进程间通信IPC.消息的接收与应答 chromium源码阅读-进程间通信IPC.消息的接收与应答 介绍 chromium进程间通信在win32下是通过命名管道的方式实现的,最后的数据都是以二进制流的方式进行传播,pickle类就是负责消息的封包与解包功能,它将各种数据已二进制的形式写到内存缓冲区中,在实际通信的时候通过与其他一些辅助类与模板函数来实现具体数据结构的写与读.本文主要介绍的是chromium在将消息发送与接收过程中,以及chromium如何通过各种消息宏与C

进程间通信---IPC对象 之 消息队列

IPC对象,既我们所说的进程间通信,下面就来总结一下都有哪些方式以及怎么使用. 一 消息队列 1 消息队列的创建: int msgget(key_t key, int msgflg); 功能:获取指定的key值的消息队列ID 参数: @key <1>IPC_PRIVATE:每次都会创建一个新的消息队列 [用在亲缘关系的进程间痛惜] <2>ftok函数获的key [用在非亲缘关系进程间通信] key_t ftok(const char *pathname, int proj_id);

Linux 进程间通信(IPC)

Linux 进程间通信(IPC): Linux系统中除了进程和进程之间通信,我想大家也应该关注用户空间与内核空间是如何通信的,比方说netlink等等.除了传统进程间通信外像Socket通信也需要掌握的! /*-------------------------------------------------------------------------- * Project: aipc.c * Name: zwp * Date: 2014/6 *------------------------

操作系统之进程篇(4)--经典进程间通信(IPC)问题

1. 哲学家进餐问题: 问题描述: 五个哲学家在一个圆桌上进餐,每人的面前放了一盘意大利面,两个盘子之间有一个叉子,但是由于盘子里面的面条十分光滑,需要两个叉子才能进行就餐行为.餐桌的布局如下图所示: 假设哲学家的生活中只有两个活动:吃饭和思考[吃饭维持自身之生存,思考探究生存之意义],当然这样的哲学家在现实之中是不存在的.当一个哲学家在殚精竭虑之时,饥饿感随之而来,这是他会拿起左右手边的两个叉子来想享用这俗世之中的美味.酒足饭饱之后,又"躲进小楼成一统,管他春夏与秋冬"去了.问题是:

Linux进程间通信(IPC)简介

Linux IPC的发展 Linux下的进程通信手段基本上是从UNIX平台上的进程通信手段继承而来的.而对UNIX发展做出重大贡献的两大主力AT&T的贝尔实验室及BSD(加州大学伯克利分校的伯克利软件发布中心)在进程间的通信方面的侧重点有所不同.前者是对UNIX早期的进程间通信手段进行了系统的改进和扩充,形成了"system V IPC",其通信进程主要局限在单个计算机内:而BSD则跳过了该限制,形成了基于套接口(socket)的进程间通信机制.而Linux则把两者的优势都继承

饿了么开源项目Hermes:新颖巧妙易用的Android进程间通信IPC框架

版权所有.所有权利保留. 欢迎转载,转载时请注明出处: http://blog.csdn.net/xiaofei_it/article/details/51464518 Android进程间通信IPC是比较高级的话题,很多Android程序员碰到IPC就觉得头疼,尤其是AIDL这类东西. 公司最近在研究DroidPlugin插件开发,DroidPlugin把每个子app都变成一个进程.这样的话子app和主app如果需要共享数据,就需要IPC.所以我开发了Hermes框架,让IPC变得非常简单优雅

进程间通信IPC:消息队列,信号量,共享内存

2015.3.4星期三 阴天 进程间通信:IPC 文件对象:记录文件描述符,文件开关等 IPC标示符:系统全局的流水号两个进程要通信,打开的是唯一的对象进行通讯,通过key操作 XSI IPC:消息队列,信号量,共享内存. ipcs 查看ip对象共享内存,信号量,消息队列等信息ipcrm 删除一个IP对象 Linux为用户提供了完善的,强大的网络功能完善的内置网络:其他操作系统不包含如此紧密的和内核结合在一起的网络部分 共享内存标示符的获取有两种方法:ftok(pathname,id)另一个是K

进程间通信(IPC)之共享内存

★IPC方法包括管道(PIPE).消息队列(Message_Queue).旗语.共用内存(ShareMemory)以及套接字 (Socket).进程间通信主要包括了管道.系统IPC(包括了消息队列.信号以及共享存储).套接字(Socket). 此文将叙述共享内存的相关内容. 在此之前先来看看关于进程的内存映像的相关内容. 一.进程的内存映像(区别于可执行程序文件): 指的是内核在内存中如何存放可执行程序文件.两者的区别表现在三个方面:①可执行程序是位于硬盘上的,而内存映像位 于内存上: ②可执行