Linux生产者消费者模型实现

2023-05-16

转载请注明出处:https://blog.csdn.net/mymottoissh/article/details/84181224

任何语言提及到多线程同步都离不开生产者/消费者模型。这也是针对许多现实问题建模用到的基础模型。这一篇就来看一下在Linux环境下,C语言实现的两种生产者和消费者模型。

关键字:Linux C 生产者 消费者

条件变量实现生产-消费模型

条件变量都会和互斥锁进行配合使用。首先来回顾一下条件变量的控制原语。

pthread_cond_init(pthread_cond_t *restrict cond, const pthread_condattr_t *restrict attr) //初始化创建
pthread_cond_destroy(pthread_cond_t *cond) //销毁
pthread_cond_wait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex) //阻塞等待条件变量,同时释放互斥量,两步为一原子操作
pthread_cond_timedwait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex, const struct timespec *restrict cond) //限时等待
pthread_cond_signal(pthread_cond_t *cond) //唤醒至少一个
pthread_cond_broadcast(pthread_cond_t *cond) //唤醒所有

在使用条件变量时,我们至少需要两个条件变量和一个互斥量

pthread_cond_t cond_not_empty = PTHREAD_COND_INITIALIZER;
pthread_cond_t cond_not_full = PTHREAD_COND_INITIALIZER;
pthread_mutex_t mutex_lock = PTHREAD_MUTEX_INITIALIZER;

那么,此时的生产消费模型应该是酱的。

条件变量 生产-消费模型

由此一来,该模型的实现就变为多线程对一临界区的操作问题。

首先是生产者

void *producer(void *arg)
{
    while(1)
    {
        prepare_data();
        pthread_mutex_lock(&mutex_lock);
        while(product_is_full())
        {
            pthread_cond_wait(&cond_not_full, &mutex_lock);
        }
        insert_data();
        pthread_mutex_unlock(&unlock);
        pthread_cond_signal(&cond_not_empty);
        sleep_for_some_time();
    }
}

然后是消费者

void *consumer(void *arg)
{
    while(1)
    {
        pthread_mutex_lock(&mutex_lock);
        while(product_is_empty())
        {
            pthread_cond_wait(&cond_not_empty, &mutex_lock);
        }
        delete_data();
        pthread_mutex_unlock(&mutex_lock);
        sleep_for_some_time();
    }
}

逻辑很清晰,只不过在使用条件变量时,重点需要注意的是pthread_cond_wait的特性及使用。在等待条件变量时,会释放互斥量,被唤醒时会重新加锁。同时考虑到有多个消费者的情况,采用了while循环加锁。

信号量实现生产-消费模型

同样,首先来回顾一下信号量的控制原语

sem_init(sem_t *sem, int pshared, unsigned int value)
sem_destroy(sem_t *sem)
sem_wait(sem_t *sem)
sem_trywait(sem_t *sem)
sem_post(sem_t *sem)

通过信号量实现的模型和条件变量略有不同。因为一个线程不应该既是生产者,又是消费者,所以同一个线程不能同时实现信号量的P和V操作。在这种情况下,应该存在两个信号量。例如,信号量的容量为10,那么同一时刻,两个信号量的当前值之和应该为10。此时,生产消费模型应该是酱的。

信号量生产消费模型

首先我们要有两个信号量

sem_init(&sem_blank, 0, 10);
sem_init(&sem_filled, 0, 0);

生产者代码

void *producer(void *arg)
{
    while(1)
    {
        sem_wait(&sem_blank);
        insert_data();
        sem_post(&sem_filled);
        sleep_for_some_time();
    }
}

消费者代码

void *consumer(void *arg)
{
    while(1)
    {
        sem_wait(&sem_filled);
        delete_data();
        sem_post(&sem_blank);
        sleep_for_some_time();
    }
}

完。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Linux生产者消费者模型实现 的相关文章

随机推荐

  • 如何为 Apple 官方 SwiftUI 示例中的图表元素加上首显动画?

    0 概览 在 Apple 官方教程示例 Animating Views and Transitions 中 苹果为我们展示了如何为 SwiftUI 中的各种视图添加动画和过渡效果 在示例的最后 我们在完成 3 种不同数据类型 Elevati
  • SwiftUI 4.0(iOS 16)极简实现一个美美哒的多选 Toggle 按钮组

    概览 在 SwiftUI 4 0 之前 xff0c 想要实现如下效果的多选 全选 Toggle 按钮组是要写不少行代码滴 xff1a 不过 xff0c 在 iOS 16 之后我们仅用1行代码即可搞定以上所有 xff01 在某些场合下这非常有
  • SwiftUI 使用 UIPageViewController 翻页后出现空白的原因及解决

    问题现象 我们 SwiftUI 开发的 App 需要 UIPageViewController 的翻页功能 这可以非常方便的通过桥接 UIKit 到 SwiftUI 来搞定 不过 观察上图可以发现 App 翻页显示的并不太对 当用户通过右下
  • SwiftUI 中 TabView 如何原生使用类 UIPageView 的翻页样式?

    功能需求 我们知道 TabView 是 SwiftUI 中非常好用的布局组织容器 它可以分类组织视图并依次展示给用户 从 SwiftUI 2 0 开始 iOS 14 0 TabView 除了常规的以标签 Tab Label 样式显示外 还可
  • SwiftUI 设计和调试复杂界面的基本技巧示例

    功能需求 对于比较复杂的 SwiftUI 界面 我们需要在充分了解 SwiftUI 各个视图基本特性的同时 合理利用 Xcode 强大的预览 Preview 机制 实时且全面的测试所有场景下的显示情况 如上图所示 我们在 App 支持的每种
  • SwiftUI 如何动态条件显示和隐藏 Toolbar 按钮且不做无谓刷新

    功能需求 在 SwiftUI 中我们可以非常容易的定制导航栏 Toolbar 中按钮的显示 包括折叠 分组和按条件动态显示和隐藏等 如上图所示 我们仅用寥寥几行代码就实现了 SwiftUI 导航栏 Toolbar 按钮的折叠 分组和按条件动
  • SwiftUI 极简实现文本摆动弹性动画

    概览 SwiftUI 为我们来了界面设计和调试上的便利 xff0c 只需几行代码我们就能实现一个不错的文本动画效果 xff1a 如上图所示 xff0c 我们在 SwiftUI 中基本还没发力 xff0c 就实现了文本摆动弹性动画 这究竟是怎
  • 美团后端笔试2022.08.13

    文章目录 昨天刚刚笔试结束 xff0c 然后今天抽空给大家整理一下 xff0c 然后简单说一下思路 整场笔试下来 xff0c 整体难度一般 xff0c 只不过在第三题扑克牌游戏的时候进行的不是很顺利 xff0c 附加题难度一般 xff0c
  • SwiftUI 如何让文本自动支持查找和替换功能?

    概览 有些情况下 xff0c 我们需要为文本编辑器实现文本的查找和替换功能 xff08 find amp replace xff09 xff0c 如果完全靠自已撸码还是比较棘手的 所幸的是 xff0c 从 SwiftUI 4 0 xff08
  • SwiftUI 新 Alert 弹出窗口圆你文本输入之梦

    概览 小伙伴们都知道 xff0c 弹出 Alert 不能包含文本输入框是 SwiftUI 的阿喀琉斯之踵 Achilles Heel 当然 xff0c 这说的有些夸张了 x1f609 不过 xff0c Alert 不能包含 TextFiel
  • SwiftUI 4.0 新 LabeledContent 视图帮您解决所有对齐烦恼

    概览 在用 SwiftUI Form 设计 App 界面时 xff0c 最头疼的就是内部视图对齐的问题了 好不容易适配了 iOS 中的布局 xff0c 到了 iPadOS 或 MacOS 上却变得一团糟 有没有一劳永逸 xff0c 简单方便
  • Xcode 使用 Instruments 无法找到代码中耗时挂起操作的解决

    问题现象 Instruments 是一套非常有用的代码分析和调试利器 我们经常用它来查找 App 中的性能瓶颈 不过 有时 Instruments 却无法捕获到系统明显挂起或长耗时的方法 这是怎么回事呢 如上图所示 App 运行中系统 Se
  • 用 DISM 命令备份与还原 Windows 系统

    一 初始备份 xff08 例如 xff1a 把 C 分区的系统备份到 D 分区的 Win8BF 文件夹中 xff0c 备份文件名为 Win8Pro wim xff09 xff1a Dism Capture Image ImageFile D
  • Unresolved reference: viewModels,viewModels()方法找不到

    遇到的问题 最近在学习LiveData和ViewModel xff0c 跟着官网敲 xff0c 碰到了以下情况 span class token keyword private span span class token keyword v
  • 天干地支计算

    年的干支 方法一 xff1a 首先要能记住十大天干和十二地支 xff0c 十天干 xff1a 甲 乙 丙 丁 戊 己 庚 辛 壬 癸 xff1b 十二地支 xff1a 子 丑 寅 卯 辰 巳 午 未 申 酉 戌 亥 xff1b 天干地支纪年
  • 程序员们,AI来了,机会来了,危机也来了

    程序员们 xff0c AI来了 xff0c 机会来了 xff0c 危机也来了 1 人工智能真的来了 纵观古今 xff0c 很少有计算机技术能有较长的发展寿命 xff0c 大部分昙花一现 xff0c 比如 xff1a 昔日的DOS windo
  • 统信UOS 20 1050 记录一次openssl升级失败的排查过程

    目录 不能找到openssl最新版本的原因 fedora有相关module的介绍 一些yum module 常用的命令 xff1a 查看yum module 都有哪些 启用禁用module 总结 xff1a 后记 xff1a 通过yum l
  • iOS之富文本

    之前做项目时遇到一个问题 xff1a 使用UITextView显示一段电影的简介 xff0c 由于字数比较多 xff0c 所以字体设置的很小 xff0c 行间距和段间距也很小 xff0c 一大段文字挤在一起看起来很别扭 xff0c 想要把行
  • JetBrains IntelliJ IDEA 2022.2 使用 Java 17 运行时

    JetBrains 发布 了 IntelliJ IDEA 2022 2 xff0c 支持 Java 17 和最新的语言和框架 xff0c 如 Scala Kotlin Spring 6 和 Spring Boot 3 这个新版本使用了 Je
  • Linux生产者消费者模型实现

    转载请注明出处 xff1a https blog csdn net mymottoissh article details 84181224 任何语言提及到多线程同步都离不开生产者 消费者模型 这也是针对许多现实问题建模用到的基础模型 这一