进程间通信
进程间通信是不同进程之间的信息传输或交换。在不同的过程中,双方可以访问哪些媒体?进程的用户空间相互独立。一般来说,他们不能互相接触。唯一的例外是共享内存区域。此外,系统空间是一个“公共场所”,所有进程都可以访问它,因此内核也可以提供这样的条件。此外,还有双方都可以访问的外围设备。当然,从这个意义上讲,两个进程也可以通过磁盘上的普通文件,或通过“注册表”或其他数据库中的一些表条目和记录来交换信息。从广义上讲,这也是进程间通信的一种手段,但通常不被视为“进程间通信”。
进程间通信(IPC,InterProcess Communication)是指在不同进程之间传播或交换信息。IPC的方式通常有管道(包括匿名管道和命名管道)、消息队列、信号量、共享内存等。
因为进程具有独立性,如果两个或者多个进程需要相互通信,就必须要看到同一份资源:就是一段内存这个内存可能以文件的方式提供,也可能以队列的方式,也可能提供的就是原始的内存块
这个公共资源应该属于谁?这个公共资源肯定不属于任何进程,如果这个资源属于进程,这个资源就不应该再让其它进程看到,要不然进程的独立性怎么保证呢?所以这个资源只能属于操作系统!
进程间通信的前提:是有OS参与,提供一份所有通信进程能看到的公共资源!
进程间通信的目的
数据传输:一个进程需要将它的数据发送给另一个进程
资源共享:多个进程之间共享同样的资源
通知事件:一个进程需要向另一个或一组进程发送消息,通知它(它们)发生了某种事件(如进程终止时要通知父进程)
进程控制:有些进程希望完全控制另一个进程的执行(如Debug进程),此时控制进程希望能够拦截另一个进程的所有陷入和异常
管道
那么提到进程间通信我们就要说到管道
管道是以一个文件的形式充当两个进程间通信的桥梁
一端写入 另外一段读出
这里就要提到 为什么管道文件是存储在内存 而不是磁盘中呢
因为内存的读取和传输速率都是要高于磁盘的 因此我们把管道文件放在内存中
可以看到我们可以创建有名管道 然后使用 open函数在一端进行写操作
再另外一端进行读操作
我们可以再Linux中用文件操作的方式来模拟进程间通信
我们可以看到 我们先打开一个管道文件 然后 循环的输入
最后将循环输入的内容存储到管道文件中
然后我们就需要从另外一端进行读操作
这样我们就模拟实现了一个进程间通信
那么基于管道的进程间通信
它会有以下特点
半双工的意思就是它只能从一端进行输入 然后一端进行读操作
然后 管道中的写端和读端会相互影响
这就是半双工
在后续的学习中我们会学习到套接字文件 这个的工作特点就是全双工
类似于微信好友互相聊天 可以一端实现读操作的时候进行写操作
复制文件描述符
在 Linux 系统中,open 返回得到的文件描述符 fd 可以进行复制,复制成功之后可以得到一个新的文件描述符,使用新的文件描述符和旧的文件描述符都可以对文件进行 IO 操作,复制得到的文件描述符和旧的文件描述符拥有相同的权限,譬如使用旧的文件描述符对文件有读写权限,那么新的文件描述符同样也具有读写权限;在 Linux 系统下,可以使用 dup 或 dup2 这两个系统调用对文件描述符进行复制,
因为复制得到的文件描述符与旧的文件描述符指向的是同一个文件表,所以可知,这两个文件描述符的属性是一样,譬如对文件的读写权限、文件状态标志、文件偏移量等,所以从这里也可知道“复制”的含义实则是复制文件表。同样,在使用完毕之后也需要使用 close 来关闭文件描述符。
dup
oldfd:需要被复制的文件描述符。
返回值:成功时将返回一个新的文件描述符,由操作系统分配,分配置原则遵循文件描述符分配原则;如果复制失败将返回-1,并且会设置 errno 值。
dup 2
oldfd:需要被复制的文件描述符。
newfd:指定一个文件描述符(需要指定一个当前进程没有使用到的文件描述符)。
返回值:成功时将返回一个新的文件描述符,也就是手动指定的文件描述符 newfd;如果复制失败将返回-1,并且会设置 errno 值。
信号量
/