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

8.线程的同步和互斥

8.线程的同步和互斥

      • **1. 线程的互斥机制**
      • **2. 线程的同步机制**
      • **3. 死锁的产生与避免**
      • **4. 练习与作业**
      • **5. 线程的分离属性**
      • **6. 线程的清理函数**
      • **7. 总结**


1. 线程的互斥机制

  • 互斥的概念:在多线程环境中,对临界资源的排他性访问。
  • 互斥锁:用于保证临界资源的访问控制。
  • 互斥锁的使用框架
    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);
      
      • 功能:对临界资源加锁,确保同一时刻只有一个线程访问。
      • 返回值:成功返回0,失败返回非零。
    4. 解锁
      int pthread_mutex_unlock(pthread_mutex_t *mutex);
      
      • 功能:释放互斥锁,允许其他线程访问临界资源。
      • 返回值:成功返回0,失败返回非零。
    5. 销毁互斥锁
      int pthread_mutex_destroy(pthread_mutex_t *mutex);
      
      • 功能:销毁互斥锁,释放资源。
      • 返回值:成功返回0,失败返回非零。
    6. 尝试加锁
      int pthread_mutex_trylock(pthread_mutex_t *mutex);
      
      • 功能:尝试加锁,若锁已被占用则立即返回,不阻塞。
      • 返回值:成功返回0,失败返回非零。

2. 线程的同步机制

  • 同步的概念:在多线程环境中,确保线程按照一定的顺序访问资源。
  • 信号量:用于实现线程间的同步。
  • 信号量的使用框架
    1. 定义信号量
      sem_t sem;
      
    2. 初始化信号量
      int sem_init(sem_t *sem, int pshared, unsigned int value);
      
      • 参数:
        • sem:要初始化的信号量。
        • pshared0表示线程间使用,非0表示进程间使用。
        • value:信号量的初始值(通常为1,表示二值信号量)。
      • 返回值:成功返回0,失败返回-1
    3. P操作(申请资源)
      int sem_wait(sem_t *sem);
      
      • 功能:申请信号量资源,若资源不可用则阻塞。
      • 返回值:成功返回0,失败返回-1
    4. V操作(释放资源)
      int sem_post(sem_t *sem);
      
      • 功能:释放信号量资源,唤醒等待的线程。
      • 返回值:成功返回0,失败返回-1
    5. 销毁信号量
      int sem_destroy(sem_t *sem);
      
      • 功能:销毁信号量,释放资源。
      • 返回值:成功返回0,失败返回-1

3. 死锁的产生与避免

  • 死锁的产生原因
    1. 系统资源不足。
    2. 进程运行推进顺序不合适。
    3. 资源分配不当。
  • 死锁的四个必要条件
    1. 互斥条件:一个资源每次只能被一个进程使用。
    2. 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。
    3. 不剥夺条件:进程已获得的资源,在未使用完之前,不能强行剥夺。
    4. 循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。
  • 避免死锁的策略
    • 破坏死锁的四个必要条件之一。
    • 使用资源分配算法(如银行家算法)避免死锁。

4. 练习与作业

  • 练习1:设计一个多线程程序,共享同一块字符数组,分别向该数组中写入字符串,使用互斥锁保证某一时刻只能有一个线程操作该数组。
  • 练习2:使用互斥锁完成多线程对指定文件的写操作,确保每个线程写入的信息不覆盖和交叉。
  • 练习3:使用信号量实现线程同步,一个线程获取用户输入信息,另一个线程统计输入信息的长度并打印输出,输入quit时程序结束。
  • 作业1:设计一个火车票售票系统,至少有两个售票窗口,确保每个窗口不重复卖票,将100张车票均匀卖出。
  • 作业2:设计一个餐厅排队系统,模拟顾客排队、叫号、就餐的过程,使用信号量和互斥锁实现同步与互斥。

5. 线程的分离属性

  • 设置分离属性
    • 方法1:使用pthread_attr_setdetachstate
      pthread_attr_t attr;
      pthread_attr_init(&attr);
      pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
      pthread_create(&tid, &attr, fun, NULL);
      pthread_attr_destroy(&attr);
      
    • 方法2:使用pthread_detach
      pthread_detach(tid);
      

6. 线程的清理函数

  • 注册清理函数
    void pthread_cleanup_push(void (*routine)(void *), void *arg);
    
  • 调用清理函数
    void pthread_cleanup_pop(int execute);
    

7. 总结

  • 互斥锁用于保证临界资源的排他性访问,信号量用于实现线程间的同步。
  • 死锁的四个必要条件:互斥条件、请求与保持条件、不剥夺条件、循环等待条件。
  • 通过合理使用互斥锁和信号量,可以避免多线程程序中的竞争条件和死锁问题。


http://www.kler.cn/a/526036.html

相关文章:

  • Redis --- 分布式锁的使用
  • 商密测评题库详解:商用密码应用安全性评估从业人员考核题库详细解析(9)
  • C++:多继承习题5
  • Java面试题2025-设计模式
  • 开发环境搭建-4:WSL 配置 docker 运行环境
  • 在无sudo权限Linux上安装 Ollama 并使用 DeepSeek-R1 模型
  • 大数据相关职位介绍之三(数据挖掘,数据安全 ,数据合规师,首席数据官,数据科学家 )
  • 解析静态链接
  • 我的毕设之路:(2)系统类型的论文写法
  • C++并发编程指南07
  • CMAKE工程编译好后自动把可执行文件传输到远程开发板
  • 深度学习探索:ChatGPT数据分析精髓 梯度下降优化方法深度剖析
  • 微软官方工具箱 PowerToys,提升工作效率
  • Conditional DETR for Fast Training Convergence论文学习
  • 负荷预测算法模型
  • 新月智能护甲系统CMIA--未来战场的守护者
  • 从巫师求雨说起
  • 如何使用formlinker,重构微软表单创建的数字生产力法则?
  • 提供算法模型管理、摄像头管理、告警管理、数据统计等功能的智慧园区开源了
  • MySQL(高级特性篇) 14 章——MySQL事务日志
  • 【memgpt】letta 课程4:基于latta框架构建MemGpt代理并与之交互
  • 如何把一个python文件打包成一步一步安装的可执行程序
  • 基于Android Studio开发平台使用CNN和LSTM的人工智能家居监控系统
  • 物业管理软件引领社区智能化转型提升服务效率与居民生活质量
  • 网站快速收录:利用新闻源的优势
  • 【外文原版书阅读】《机器学习前置知识》2.用看电影推荐的例子带你深入了解向量点积在机器学习的作用