当前位置: 首页 > news >正文

信号量、死锁、管道

  • 一、信号量
    • 信号量是一种用于线程间或进程间同步的机制,它可以用来控制对共享资源的访问,协调线程的执行顺序
    • 线程间同步机制:让多个线程在执行某个任务时,具有先后顺序的执行
    • 信号量的基本概念
      • 信号量是一个整型变量,支持两种原子操作:
      • ​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通信
      • 网络通信
http://www.lryc.cn/news/624642.html

相关文章:

  • 【Goland】:Map
  • 【UE4】VS2022编译UE4.26.2工程问题记录
  • 基于CentOS 7.6搭建GitLab服务器【玩转华为云】
  • css中px转rem的计算公式
  • L/S/C频段航空航天使用情况
  • ​​Java核心知识体系与集合扩容机制深度解析​
  • MYSQL中读提交的理解
  • 跨平台笔记协作:cpolar 提升 Obsidian 知识库共享效率方案
  • ubuntu 下载安装tomcat简单配置(傻瓜式教程)
  • Fluss:颠覆Kafka的面向分析的实时流存储
  • RAG 入门指南:从概念到最小系统搭建
  • 一道同分排名的SQL题
  • Vue深入组件:组件 v-model 详解2
  • Windows从零到一安装KingbaseES数据库及使用ksql工具连接全指南
  • DSP音频算法工程师技能2
  • PPT生成视频的AI大模型应用技巧
  • 如何区分网站使用的是Vue2还是Vue3
  • 电梯的构造|保养|维修视频全集_电梯安全与故障救援(课程下载)
  • 计算机视觉 图像处理 在两张二值图中检测线条交集点的高效方法 适合工程图纸比对、生物神经元网络分析和文档特征提取等场景 ,
  • 数据仓库理论
  • 什么叫做 “可迭代的产品矩阵”?如何落地?​
  • 密码管理中随机数安全修复方案
  • 飞算JavaAI家庭记账系统:从收支记录到财务分析的全流程管理方案
  • GISer大事件,保研考研竞赛时间线一览
  • echarts实现3个y轴的图表
  • Mysql核心框架知识
  • 深度剖析PyTorch分布式训练:从原理到工程实践
  • 后端通用基础代码
  • AC3 用户认证技术
  • 用一个label控件随便显示一些字(用矢量字库),然后用anim动画动态设置lable位置