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

学习嵌入式的第二十九天-数据结构-(2025.7.16)线程控制:互斥与同步

以下是您提供的文本内容的排版整理版本。我已根据内容主题将其分为几个主要部分(互斥锁、信号量、死锁、IPC进程间通信、管道操作),并使用清晰的结构组织信息:

  • 代码片段用代码块格式(指定语言为C)突出显示。
  • 函数定义和步骤使用有序列表整理。
  • 关键概念用加粗或小标题强调。
  • 整体结构基于逻辑顺序优化,确保易读性,但未修改原始内容含义。

互斥锁机制

互斥机制确保多线程中对临界资源的排他性访问(公共资源)。框架包括定义、初始化、加锁、解锁和销毁步骤。

  1. 定义互斥锁

    pthread_mutex_t mutex; // 互斥锁类型变量
    

  2. 初始化锁

    • 函数:int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr);
      • 功能:初始化已定义的互斥锁。
      • 参数:
        • mutex:要初始化的互斥锁指针。
        • attr:初始化属性值,通常为NULL(表示默认锁)。
      • 返回值:成功返回0,失败返回非零值。
  3. 加锁

    • 函数:int pthread_mutex_lock(pthread_mutex_t *mutex);
      • 功能:对指定代码加锁,加锁后代码为原子操作(其他线程无法访问)。
      • 参数:mutex为互斥锁指针。
      • 返回值:成功返回0,失败返回非零值。
      • 注意:如果锁已被占用,则阻塞当前线程。
  4. 解锁

    • 函数:int pthread_mutex_unlock(pthread_mutex_t *mutex);
      • 功能:解锁指定互斥锁。
      • 参数:mutex为互斥锁指针。
      • 返回值:成功返回0,失败返回非零值。
      • 注意:加锁和解锁通常成对出现。
  5. 销毁锁

    • 函数:int pthread_mutex_destroy(pthread_mutex_t *mutex);
      • 功能:销毁互斥锁。
      • 参数:mutex为互斥锁指针。
      • 返回值:成功返回0,失败返回非零值。
  6. 非阻塞锁(trylock)

    • 函数:int pthread_mutex_trylock(pthread_mutex_t *mutex);
      • 功能:类似加锁,但不阻塞。
      • 参数:mutex为互斥锁指针。
      • 返回值:成功返回0,失败返回非零值(如EAGAIN)。
    • 注意:互斥锁控制排他访问,但不保证次序。

信号量机制(Linux线程同步)

信号量用于线程或进程间同步,分类为:

  • 无名信号量:线程间通信。
  • 有名信号量:进程间通信。

框架包括定义、初始化、PV操作和销毁。

  1. 定义信号量

    sem_t sem; // 信号量类型变量
    

  2. 初始化信号量

    • 函数:int sem_init(sem_t *sem, int pshared, unsigned int value);
      • 功能:初始化已定义的信号量。
      • 参数:
        • sem:信号量指针。
        • pshared0表示线程间使用,非0表示进程间使用。
        • value:初始值(例如,二值信号量中,0表示阻塞,1表示通过)。
      • 返回值:成功返回0,失败返回非零值。
  3. PV操作

    • P操作(申请资源):sem_wait(sem_t *sem);(功能:减少信号量值,如果值为0则阻塞)。
    • V操作(释放资源):sem_post(sem_t *sem);(功能:增加信号量值,唤醒等待线程)。
    • 注意:PV操作确保同步。
  4. 销毁信号量

    • 函数:int sem_destroy(sem_t *sem);
      • 功能:销毁信号量。
      • 参数:sem为信号量指针。
      • 返回值:成功返回0,失败返回非零值。

死锁原因与必要条件

死锁产生原因:

  1. 系统资源不足。
  2. 进程运行推进顺序不合适。
  3. 资源分配不当。

死锁必要条件:

  1. 互斥条件:一个资源每次只能被一个进程使用。
  2. 请求与保持条件:进程因请求资源阻塞时,对已获得资源保持不放。
  3. 不剥夺条件:进程已获得资源在未使用完前不能被强行剥夺。
  4. 循环等待条件:若干进程形成头尾相接的循环等待资源关系。

注意:如果资源充足,死锁可能性低;否则易因争夺资源发生。


IPC进程间通信分类

IPC(Inter-Process Communicate)分为三大类:

  1. 古老通信方式

    • 无名管道。
    • 有名管道。
    • 信号(唯一异步通信方式)。
  2. IPC对象通信(System V)

    • 消息队列(较少使用)。
    • 共享内存(最高效方式)。
    • 信号量集。
  3. Socket通信:用于网络通信。

特例:线程信号使用sem_init(POSIX标准)。


管道操作(有名管道)

管道操作框架:打开、读写、关闭、卸载。

  1. 打开有名管道

    • 函数:int open(const char *pathname, int flags);
      • 注意:
        • 管道为半双工模式,打开方式决定读写端。
        • 示例:
          int fd_read = open("./fifo", O_RDONLY); // 固定为读端
          int fd_write = open("./fifo", O_WRONLY); // 固定为写端
          

        • 禁止使用O_RDWR(读写模式)或O_CREAT(创建选项),管道创建需用mkfifo函数。
  2. 管道读写

    • 读操作:read(fd_read, buff, sizeof(buff));
    • 写操作:write(fd_write, buff, sizeof(buff));
  3. 关闭管道

    • 函数:close(fd);
  4. 卸载管道

    • 函数:int unlink(const char *pathname);
      • 功能:移除管道文件。

http://www.dtcms.com/a/297262.html

相关文章:

  • 【运维】ubuntu 安装图形化界面
  • 顺应AI浪潮,电科金仓数据库再创辉煌
  • 继承接口实现websocke,实现任意路径链接
  • 可以修改公网ip吗
  • X-plore File Manager v4.34.02 修改版:安卓设备上的全能文件管理器
  • 海云安斩获“智能金融创新应用“标杆案例 彰显AI安全左移技术创新实力
  • 快速入门Socket编程——封装一套便捷的Socket编程——Reactor
  • 【AMD平台】编译llama.cpp
  • 【问题集】——RAG项目实战:LangChain 0.3集成 Milvus 2.5向量数据库,构建大模型智能应用
  • GTSuite许可与网络安全
  • 每天算法刷题Day53:7.25:leetcode 栈5道题,用时1h35min
  • 广东省省考备考(第五十六天7.25)——常识:科技常识(听课后强化训练)
  • 输电线路观冰精灵在线监测装置:科技赋能电网安全的新利器
  • 微算法科技(NASDAQ:MLGO)采用分布式哈希表优化区块链索引结构,提高区块链检索效率
  • 在FreeBSD系统下使用llama-cpp运行飞桨开源大模型Ernie4.5 0.3B(失败)
  • C++ atomic与内存顺序 【转】
  • 从双碳到零碳园区:安科瑞微电网系统的应用与价值
  • Javaweb————学习javaweb的预备知识
  • 【数据结构】长幼有序:树、二叉树、堆与TOP-K问题的层次解析(含源码)
  • 【js】Proxy学习笔记
  • 【高等数学】第五章 定积分——第四节 反常积分
  • Colab中如何临时使用udocker(以MinIO为例)
  • 华为云DRS实现Oracle到GaussDB数据库迁移的全流程技术方案
  • Android Studio 自带的官方模拟器,ABI这一列是x86_64,xABI这一列是arm64-v8a
  • 【面试场景题】外卖点餐系统设计思路
  • mysql 和oracle的选择
  • Android Studio 2024 内嵌 Unity 3D 开发示例
  • Oracle转Mysql建表脚本
  • Android studio自带的Android模拟器都是x86架构的吗,需要把arm架构的app翻译成x86指令?
  • 【Android Studio】安装Trae插件后Android Studio 启动崩溃问题处理