IO进程 day06

10. 线程间的通信机制

10.5. 死锁

 是指两个或两个以上的进程/线程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去

死锁产生的必要条件

  1. 互斥使用,即当资源被一个线程使用(占有)时,别的线程不能使用
  2. 不可抢占,资源请求者不能强制从资源占有者手中夺取资源,资源只能由资源占有者主动释放。
  3. 请求和保持,即当资源请求者在请求其他的资源的同时保持对原有资源的占有。
  4. 循环等待,即存在一个等待队列:P1占有P2的资源,P2占有P3的资源,P3占有P1的资源。这样就形成了一个等待环路。
    注意当上述四个条件都成立的时候,便形成死锁。当然,死锁的情况下如果打破上述任何一个条件,便可让死锁消失。

11. 进程间通信机制

11.1. 进程间的通信方式

  1. 传统的通信方式:无名管道,有名管道,信号
  2. system V IPC对象:共享内存,消息队列,信号灯集
  3. BSD:套接字

11.2.无名管道

特点

  1. 只能用于具有亲缘关系的进程之间的通信
  2. 半双工的通信模式
  3. 管道可以看成是一种特殊的文件,对于它的读写可以使用文件IO如read、write函数.
  4. 管道是基于文件描述符的通信方式。当一个管道建立时,它会创建两个文件描述fd[0]和fd[1]。其中fd[0]固定用于读管道,fd[1]固定用于写管道。

pipe

#include <unistd.h>
int pipe(int pipefd[2]);

 功能:创建无名管道
 参数:int pipefd[2]创建的文件描述符,下标为0,1对应两个文件描述符
 返回值:成功返回0,失败返回EOF
注意

  1. 管道中读取空了之后,没有数据时,读取阻塞
    char buf[32] = "";     // 写入和读取的地址
	// 管道中没有数据时,读取阻塞
	read(pipefd[0], buf, 5);
	printf("buf = %s\n", buf);
  1. 管道中写满了数据,写入阻塞,写满:64k,至少读出4k空间才能进行写操作
    char full[65536] = "";	// 写满(64k = 65536)
    char arr[4096] = "";	// 空出4k空间
    // 管道中写满数据时,写入阻塞
    write(pipefd[1], full, 65536);
	// 读出4k空间
	read (pipefd[0], arr, 4096);
	
    printf("write befor\n");
    write(pipefd[1], "a", 1);
    printf("write after\n");
  1. 关闭读端,写操作会导致管道破裂,进程结束,收到SIGPIPE
    // 关闭读端,写操作会导致管道破裂,进程结束,收到SIGPIPE
    close(pipefd[0]);
    write(pipefd[1], "a", 1);
    printf("write after\n");

11.3. 有名管道

特点

  1. 有名管道可以使互不相关的两个进程互相通信
  2. 有名管道可以通过路径名来指出,并且在文件系统中可见,但内容存放在内存中
  3. 通过文件IO来操作
  4. 先进先出
  5. 写满和读空时阻塞
  6. 不支持lseek操作

mkfifo

#include <sys/types.h>
#include <sys/stat.h>
int mkfifo(const char *pathname, mode_t mode);

 功能:创建有名管道
 参数:
  const char *pathname管道文件名
  mode_t mode文件权限,8进制数表示0777
 返回值:成功返回0,失败返回EOF,更新error
注意

  1. 在打开管道时,只有完成读端和写端都打开的操作后,才会完成打开管道文件的操作,否则会在打开管道文件的位置阻塞
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值