进程间通信
管道
管道是一种2个进程进行单向通信的机制。
通过管道通信的2个进程,1个进程向管道写数据,另外1个进程从管道的另一端读数据。写入的数据每次都添加在管道缓冲区的末尾,读数据的时候都是从缓冲区的头部读出数据.
管道是1个特殊的文件,这个文件只存在于内存中。创建管道时,系统为管道分配一个页面作为数据缓冲区。
对于一些简单的进程间通信,管道还是可以完全胜任的
管道的局限:
- 没有名字
- 缓冲区大小受限制
- 所传的是无格式的字节流
- 只能用于父子进程或者兄弟进程的通信
- 数据只能由1个进程流向另一个进程,如果要进行全双工,需要建立2个管道
1.创建管道
#include #include
int pipe(int fd[2])//调用成功返回0,并且数组中将包含2个新的文件描述符,有错误发生返回-1
管道两端分别用描述符fd[0]表示管道读端,fd[1]表示管道写端。反着用会出错。
如果读进程不读走管道缓冲区的数据,写操作阻塞等待。
如果写进程没有往缓冲区写数据,读操作阻塞等待。
文件描述符
文件描述符在形式上是一个非负整数。实际上,它是一个索引值,指向[内核](https://baike.baidu.com/item/内核)为每一个进程所维护的该进程打开文件的记录表。当程序打开一个现有文件或者创建一个新文件时,内核向进程返回一个文件描述符。在程序设计中,一些涉及底层的程序编写往往会围绕着文件描述符展开。但是文件描述符这一概念往往只适用于[UNIX](https://baike.baidu.com/item/UNIX)、[Linux](文件描述符在形式上是一个非负整数。实际上,它是一个索引值,指向[内核](https://baike.baidu.com/item/内核)为每一个进程所维护的该进程打开文件的记录表。当程序打开一个现有文件或者创建一个新文件时,内核向进程返回一个文件描述符。在程序设计中,一些涉及底层的程序编写往往会围绕着文件描述符展开。但是文件描述符这一概念往往只适用于[UNIX](https://baike.baidu.com/item/UNIX)、[Linux](https://baike.baidu.com/item/Linux)这样的操作系统。
习惯上,标准输入(standard input)的文件描述符是 0,标准输出(standard output)是 1,标准错误(standard error)是 2。尽管这种习惯并非[Unix](https://baike.baidu.com/item/Unix)内核的特性,但是因为一些 shell 和很多应用程序都使用这种习惯,因此,如果内核不遵循这种习惯的话,很多应用程序将不能使用。
POSIX 定义了 STDIN_FILENO、STDOUT_FILENO 和 STDERR_FILENO 来代替 0、1、2。这三个[符号常量](https://baike.baidu.com/item/符号常量)的定义位于头文件 unistd.h。
文件描述符的有效范围是 0 到 OPEN_MAX。一般来说,每个进程最多可以打开 64 个文件(0 — 63)
2.管道的一般用法
3.dup()和dup2()函数:复制文件描述符
#include #include
int dup(int oldfd);
int dup2(int oldfd,int newfd);
dup()和dup2()函数成功时均返回1个oldfd文件描述符的父辈,失败则返回-1.
dup函数返回的文件描述符是当前可用文件描述符中的最小数值:
dup(fd[0])返回0:表示将fd[0]复制到返回的描述符
dup(fd[0])返回0:表示将fd[0]复制到返回的描述符0
- dup2函数可利用参数newfd指定想返回的文件描述符.
4.管道的应用实例
管道的一种常见用法:在父进程创建子进程后向子进程传递参数,
有名管道
消息队列
1.基本概念
消息队列是存放在内核中的消息链表,每个消息队列由消息队列标识。只有OS重启或者显示的删除1个消息队列时,该消息队列才会被真正删除.
操作消息队列时,需要用到一些数据结构,熟悉这些数据结构是掌握消息队列的关键。
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!