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

同步与互斥(同步)

线程同步

条件变量

  • 当⼀个线程互斥地访问某个变量时,它可能发现在其它线程改变状态之前,它什么也做不了。
  • 例如⼀个线程访问队列时,发现队列为空,它只能等待,只到其它线程将⼀个节点添加到队列中。这种情况就需要⽤到条件变量。

同步概念与竞态条件

  • 同步:在保证数据安全的前提下,让线程能够按照某种特定的顺序访问临界资源,从⽽有效避免 饥饿问题,叫做同步
  • 竞态条件:因为时序问题,⽽导致程序异常,我们称之为竞态条件。在线程场景下,这种问题也不难理解

总结:

  • 互斥能保证安全性,但是安全不一定合理和高效.                 用互斥量来实现互斥
  • 同步在安全的前提下 ,让系统变得合理和高效                     用条件变量来实现同步
  • 条件变量= 通知 + 等待队列              
  • 条件变量能够使线程同步 ,用对列维护线程顺序

条件变量函数

初始化

方法1: 这种初始化使用的是局部条件变量 ,后面需要销毁

int pthread_cond_init(pthread_cond_t *restrict cond,const pthread_condattr_t *restrict attr);参数:cond:要初始化的条件变量attr:NULL

方法2: 使用全局条件变量, 后续不用销毁了 ,类似互斥量 

pthread_cond_t cond = PTHREAD_COND_INITIALIZER;

销毁

int pthread_cond_destroy(pthread_cond_t *cond)

线程等待条件满足 ,不满足就在等待对列中阻塞(在此函数中阻塞)

int pthread_cond_wait(pthread_cond_t *restrict cond,pthread_mutex_t *restrict 
mutex);参数:cond:要在这个条件变量上等待mutex:互斥量,后⾯详细解释(等的时候会自动释放传来的锁 ,进入函数内部阻塞 ,唤醒时会自动持有锁)

唤醒等待队列中的线程

 int pthread_cond_broadcast(pthread_cond_t *cond);  唤醒等待对列中全部的线程int pthread_cond_signal(pthread_cond_t *cond);     唤醒等待对列中第一个线程

简单案例:

我们先使⽤PTHREAD_COND/MUTEX_INITIALIZER进⾏测试,对其他细节暂不追究

然后将接⼝更改成为使⽤ pthread_cond_init / pthread_cond_destroy 的⽅式, ⽅便后 续进⾏封装

#include <iostream>
#include <cstdio>
#include <string>
#include <pthread.h>
#include <unistd.h>pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;void *active(void *arg)
{std::string name = static_cast<const char *>(arg);while (true){pthread_mutex_lock(&mutex);// 没有对于资源是否就绪的判定pthread_cond_wait(&cond, &mutex); // mutex??printf("%s is active!\n", name.c_str());pthread_mutex_unlock(&mutex);}
}int main()
{pthread_t tid1, tid2, tid3;pthread_create(&tid1, nullptr, active, (void *)"thread-1");pthread_create(&tid2, nullptr, active, (void *)"thread-2");pthread_create(&tid3, nullptr, active, (void *)"thread-3");sleep(1);printf("Main thread ctrl begin...\n");while (true){printf("main wakeup thread...\n");// pthread_cond_signal(&cond);pthread_cond_broadcast(&cond);sleep(1);}pthread_join(tid1, nullptr);pthread_join(tid2, nullptr);pthread_join(tid3, nullptr);
}

http://www.xdnf.cn/news/3009.html

相关文章:

  • 【android bluetooth 案例分析 03】【PTS 测试 】【PBAP/PCE/SSM/BV-02-C】
  • 数据中心网络架构:高效规划与自动化设计实践
  • Android 系统发展史
  • php学习笔记(全面且适合新手)
  • Android的Imageview的src属性,如果设置width和height,但是图片本身很小,那么图片会自动缩放到Imageview一样的大小吗
  • GEE进行Theil-Sen Median斜率估计和Mann-Kendall检验
  • RK3568下背光控制 软件与调试技巧
  • 使用 TypeScript 开发并发布一个 npm 包(完整指南)
  • 小刚说C语言刷题——1032分糖果
  • 守护天空安全的科技利剑鼎讯信通(ACNN)的创新实践
  • Flume启动报错
  • MIT6.S081 - Lab11 networking(网络栈)
  • 阿里千问Qwen3技术解析与部署指南 :混合推理架构突破性优势与对DeepSeek R1的全面超越
  • Scrapy框架之CrawlSpider爬虫 实战 详解
  • 23种设计模式-行为型模式之解释器模式(Java版本)
  • Leetcode 3529. Count Cells in Overlapping Horizontal and Vertical Substrings
  • 关于汇编语言与程序设计——子程序设计
  • Android WIFI体系
  • Vue基础(一) 基础用法
  • 【Delphi】简化数据库读写(Helper)
  • Canvas基础篇:绘制矩形
  • 废品回收小程序:全链路数字化解决方案,赋能绿色未来
  • SDC命令详解:使用get_nets命令进行查询
  • windows如何使用cmd命令翻转屏幕
  • 多源数据整合与数据虚拟化:构建灵活、高效的数据架构
  • RPG2.设置角色摄像机
  • js day9
  • 按键精灵安卓ios辅助工具脚本:实用的文件插件(lua开源)
  • 解决ktransformers v0.3 docker镜像中 operator torchvision::nms does not exist 问题
  • Redis入门到实战——基础篇