时隔很久,再来更博...
今天主要写的是Linux中进程间通讯,进程间进行通讯的目的就是多个进程之间数据互相交换。
进程间通讯方式有以下几种:
1、信号
2、管道:分为有名管道和无名管道
3、信号量
4、消息队列
5、共享存储(共享内存)
6、套接字(socket)
其中套接字属于多机通讯(全双工通讯),其余的属于单机通讯(半双工通讯),所谓的半双工通讯就是在同一时刻里信息只能有一个传输方向,生活中的例子比如对讲机。全双工通讯即通讯的双方可以同时发送和接受消息。
管道原理:
这次我们主要讲管道中的有名管道。需要注意的是在内存中创建一个管道,他不属于进程。
有名管道:应用于任意两个进程之间数据的单向传递。在文件目录树中有一个文件标示(管道文件),实际不占据磁盘空间,数据缓存在内存上。
下来我们来看看其具体操作:
1、创建:命令方式:mkfifo 函数方式:mkfifo
2、打开:open
3、写数据:write
4、读数据:read
5、关闭:close
Linux中一切皆文件,所以打开,读写,关闭操作和文件操作一样。
下面我们写一个例子:进程A将"hello word"写入管道,进程B从管道中读取"hello word"并打印出来。
a.c
b.c
执行时我们会发现不论先执行之中哪一个可执行文件,都会发生阻塞,结果出不来。
我们先执行a,会发现:
我们再开一个终端执行b后,程序就正常执行。
出现上面的现象这是因为阻塞运行函数。
阻塞运行函数:函数调用以后不会立即返回,需要等待某些条件的发生才会返回,open操作管道文件时,会阻塞运行的函数。
如果我们再a.c中加入sleep(10),让他睡眠10秒在执行后面的程序,会出现什么情况呢?
a.c:
先执行a再执行b后出现了如下情况
过了10秒后出现以下结果
分析:执行后出现了fifo open success的字样不过没有结果,因为在write前a sleep了10秒,所以没有将东西写入管道,b就在等待a写入,所以就阻塞在那里,直到a写入后,b从管道里读取,并打印出来。
如果一个进程以只写的方式打开一个管道文件,open会阻塞运行,直到有一个进程以读的方式打开管道文件,open才会返回,进程才会接着执行。
如果一个进程以只读的方式打开一个管道文件,open会阻塞运行,直到有一个进程以写的方式打开管道文件,open才会返回,进程才会接着执行。
简单来说,写入了才会读,要读必须要写入。
read函数也会阻塞运行,直到写端写入数据或者所有的写端都关闭。
read函数读取数据并且会将内存上的已读数据清空。