信号量、死锁、管道

  • 一、信号量
    • 信号量是一种用于线程间或进程间同步的机制,它可以用来控制对共享资源的访问,协调线程的执行顺序
    • 线程间同步机制:让多个线程在执行某个任务时,具有先后顺序的执行
    • 信号量的基本概念
      • 信号量是一个整型变量,支持两种原子操作:
      • ​P操作(wait)​:尝试获取信号量,如果信号量值>0则减1并继续,否则阻塞
      • V操作(post)​:释放信号量,将信号量值加1并唤醒等待的线程
    • 操作步骤:头文件include<semaphore.h>
      • 定义信号量对象
        • sem_t
      • 初始化信号量
        • int sem_init(sem_t *sem, int pshared, unsigned int value);
          • 功能:初始化信号量
          • 参数:sem:要初始化的信号量的地址(指针);pshared:0表示线程间共享,非0表示进程间共享;value:信号量的初始值(0/1)
          • 返回值:成功:0;失败-1
      • 申请信号量:P操作
        • int sem_wait(sem_t *sem);
      • 释放信号量:V操作
        • int sem_post(sem_t *sem);
      • 销毁信号量
        • int sem_destroy(sem_t *sem);
  • 二、死锁
    • 在多线程编程中,当需要同时获取多个锁时,不正确的加锁顺序可能导致死锁。死锁是指两个或多个线程互相等待对方持有的锁,导致所有线程都无法继续执行的情况
    • 死锁的四个必要条件
      • ​互斥条件​:资源一次只能由一个线程持有
      • ​请求与保持条件​:线程持有至少一个资源,并等待获取其他资源
      • ​不剥夺条件​:已分配给线程的资源不能被其他线程强行夺取
      • 循环等待条件​:存在一个线程的循环链,每个线程都在等待下一个线程所持有的资源
    • 解决方法
      • 1.锁一定要成对出现
      • 2.使线程的加锁顺序一致
      • 3.破坏环路等待条件
      • 使用非阻塞锁,一旦线程发现请求的锁被使用,就去释放自己拥有的锁
      • pthread_mutex_trylock();
      • int sem_trywait(sem_t *sem)
  • 三、进程间通信:IPC机制
    • 进程间通信是指在不同进程之间传递数据或信号的机制
    • 同一主机进程间通信
      • 无名管道(pipe)
        • 只能用于同一主机具有亲缘关系的进程间的通信(父子进程)
        • 操作流程
          • 创建无名管道:pipe()
            • pipefd[0]---->读端
            • pipefd[1]---->写端
          • 写管道---->write
          • 读管道---->read
          • 关闭管道---->close
        • 无名管道默认大小:65536bytes=64K
        • 管道的特性:
          • 写阻塞:读端和写端都存在,向管道中写数据,当管道满时,发生写阻塞
          • 读阻塞:读端和写端都存在,从管道中读数据,若管道为空,则发生读阻塞
          • 读返回0:当写端关闭,从管道中读数据,若管道中有数据,则读到数据;若管道中没有数据,read则返回0,不再阻塞
          • 管道破裂:读端关闭,向管道中写入数据,发生管道破裂(异常)
      • 有名管道(FIFO)
        • 可以用于同一主机任意进程间通信
        • 通过文件系统中的特殊文件访问
        • 操作流程:
          • 创建管道文件:mkfifo()
            • int mkfifo(const char *pathname, mode_t mode)
              • 功能:创建一个管道文件
              • 参数:pathname:管道文件的名称;mode:管道文件的读写执行权限
              • 返回值:成功:0;失败-1
          • 打开管道文件:open()
          • 写管道文件:write()
          • 读管道文件:read()
          • 关闭管道文件:close()
          • 删除管道文件:remove()
            • intremove(const char*pathname)
      • 信号量
      • 共享内存
      • 消息队列
      • 信号量集
    • 在不同主机进程间通信
      • socket通信
      • 网络通信
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值