Linux入门学习12

IPC方法

Linux环境下,进程地址空间相互独立,每个进程各自有不同的用户地址空间。任何一个进程的全局变量 在另一个进程中都看不到,所以进程和进程之间不能相互访问,要交换数据必须通过内核,在内核中开 辟一块缓冲区,进程1把数据从用户空间拷到内核缓区,进程2再从内核缓冲区把数据读走,内核提供的这种机制称为进程间通信

常用的进程问通信方式有:

①管道(使用最简单)。

②信号(开销最小)

③共享映射区(无血缘关系)。

④本地套接字(最稳定)。

Pipe管道

  1. 概念: 管道是linux中进程间通信的一种方式,作用于有血缘关系的进程之间,完成数据传递

  1. 调用pipe系统函数即可创建一个管道,有如下特征:
  1. 它只能用于具有亲缘关系的进程之间的通信(也就是父子进程或兄弟进程之间);
  2. 它是一个半双工的通信模式,具有固定的读端和写端;
  3. 管道也可以看成是一种特殊的文件,对于它的读写也可以使用普遍的read()、write()等函数。但它 不是普通的文件,并不属于其他任何文件系统并且只存在于内存中,内核缓冲区(4k)实现。

  1. 管道的局限性:

①数据不能进程自己写,自己读。

②管道中数据不可反复读取。一旦读走,管道中不再存在。

③采用半双工通信方式,数据只能在单方向上流动。

④只能在有公共祖先的进程间使用管道

  1. 常见的通信方式有,

单工通信(收音机):只能由一方进行传输,另一方进行接收

半双工通信(对讲机):双方都可以进行传输,单上一方进行传输时,另一方无法进行传输

全双工通信(手机):双方都可以随时进行传输

管道关闭时只需要将这两个文件描述符关闭即可,可使用普通的close()函数逐个关闭各个文件描述符。

  1. Pipe函数

Int pipe(int fd[2]),其中fd[0]固定用于读端,fd[1]固定用于写端

管道创建成功以后,创建该管道的进程(父进程)同时掌握着管道的读端和写端。以下步骤为使用管道进行传输信息:

  1. 父进程调用pipe函数创建管道,得到两个文件描述符fd[0]、fd[1]指向管道的读端和写端。
  2. 父进程调用fork创建子进程,那么子进程也有两个文件描述符指向同一管道。
  3. 父进程关闭管道读端,子进程关闭管道写端。父进程可以向管道中写入数据,子进程将管道中的数据读出。

由于管道是利用环形队列实现的,数据从写端流入管道,丛读端流出,这样就实现了进程间通信。

6.管道的读写

①读管道:

  1. 管道中有数据,

1)read返回实际读到的字节数,一旦数据读走,就没有数据了。

2)可以允许多个读端,但存在竞争关系,速度快的进程读走后,数据就没有了。

2.管道中无数据:

1)管道写端被全部关闭,read 返回0(好像读到文件结尾)。

2)写端没有全部被关闭,read 阻塞等待

②写管道:

  1. 管道读端全部被关闭,进程异常终止
  2. 管道读端没有全部关闭:

(1)管道已满,write 阻塞。

(2)管道未满,write 将数据写入,并返回实际写入的字节数。

(3)可以允许多个写端,但存在竞争关系,读会阻塞第一个写的进程,一旦读到内容,就读 取结束,如果多个写在读之前已全部写完,则全部拿出。

7.标准流函数popen()函数

与linux的文件操作中有基于文件流的标准I/O操作一样,管道的操作也支持基于文件流的模式。

FILE * popen( const char * command,const char * type);

如果 type 为 r,那么调用进程读进 command 的标准输出stdout。

如果 type 为 w,那么调用进程写到 command 的标准输入stdin。

若成功则返回文件指针,否则返回NULL,错误原因存于errno中。

  1. FIFIO有名管道

有名管道(FIFO)是对无名管道的一种改进,它具有以下特点:

  1. 它可以使互不相关的两个进程间实现彼此通信;
  2. 该管道可以通过路径名来指出,并且在文件系统中是可见的。在建立了管道后,两个进程就可以 把它当做普通文件一样进行读写操作,使用非常方便;
  3. FIFO严格地遵循先进先出规则,对管道及FIFO的读总是从开始处返回数据,对它们的写则是把数 据添加到末尾,它们不支持如 lseek()等文件定位操作。

命令:mkfifo 管道名

int mkfifo(const char *pathname,mode_t mode);

FIFO通信使用

默认方式:

  1. 如果FIFO读没有打开,无法写入内容,write可能处于阻塞状态,当读打开之后,就会立即写入内 容,或者成功write一次后,自动退出
  2. 如果FIFO写没有打开,无法读入内容,read处于阻塞状态,当写如内容后,就会立即读到
  3. 当unlink()取消有名管道后,write会自动停止,read可能也会停止

对于读可以设置阻塞和非阻塞

若该管道是阻塞打开,且当前FIFO内没有数据,则对读进程而言将一直阻塞到有据写入。

若该管道是非阻塞打开而不能写入全部数据,则读操作进行部分写入或者调用失败。

access函数确定访问权限

access()函数的功能是确定文件或文件夹的访问权限,即检查某个文件的存取方式,比如说是只读方式、只写方式等。如果指定的存取方式有效,则函数返回0,否则函数返回-1。

access_wfifo.c负责写内容

access_rfifo.c负责读内容

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

简欧k

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值