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

条件变量解决同步问题之打印金鱼

说明

本代码为jyy老师上课演示条件变量解决同步问题示例(本人只做记录与分享)
本人未使用老师封装的POSIX线程库, 直接在单文件中调试并注释

问题描述

有三类线程
T1 若干: 死循环打印<
T2 若干: 死循环打印>
T3 若干: 死循环打印_
任务:
对线程同步,使得屏幕打印出<><__><>的组合

状态机

在这里插入图片描述

代码

#include <pthread.h>
#include <iostream>
#include <assert.h>
#include <string>
#include <vector>#define Lock(x) pthread_mutex_lock(x) 
#define UnLock(x) pthread_mutex_unlock(x)// 状态机的状态, 从1开始编号
enum { A = 1, B, C, D, E, F, };
// 构建状态机的
struct rule {int from, ch, to;
};
std::vector<rule> rules = {// <><{A, '<', B},{B, '>', C},{C, '<', D},// ><>{A, '>', E},{E, '<', F},{F, '>', D},// D是打印出一条鱼后停留的状态, // 需要经过'_'到初始状态A, 重新打印鱼{D, '_', A},
};
// 当前状态
int current_state = A;pthread_mutex_t lk = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cv = PTHREAD_COND_INITIALIZER;/*** 检查当前状态是否又ch这条出边* 返回0表示无法根据ch转移到一个状态
*/
int next(char ch) {// 检查ch是否是当前状态的出边for (const auto& rule : rules) {if (rule.from == current_state && rule.ch == ch) {return rule.to;}}return 0;
}
/*** 检查同步条件是否满足
*/
static int can_print(char ch) {return next(ch) != 0;
}
// 创建12个线程, 每4个打印同种字符
std::string charlib = ".<<<<<>>>>___";void* fish_thread(void* arg) {int id = *((int *)arg);char role = charlib[id];while (true) {// 先上锁Lock(&lk);// 再检查条件变量while (!can_print(role)) {pthread_cond_wait(&cv, &lk);}putchar(role); // Not lock-protected// 更新到下一个状态current_state = next(role);assert(current_state);// 更新状态后可能会使得等待该条件的线程满足条件pthread_cond_broadcast(&cv);UnLock(&lk);}
}int main() {std::vector<pthread_t> threads(charlib.size());std::vector<int> pid(charlib.size());for (int i = 0; i < charlib.size(); i++) {pid[i] = i + 1;pthread_create(&threads[i], nullptr, &fish_thread, &pid[i]);}for (int i = 0; i < charlib.size(); i++) {pthread_join(threads[i], nullptr);}
}
http://www.lryc.cn/news/347026.html

相关文章:

  • 10分钟了解Golang泛型
  • 鸿蒙内核源码分析(Shell解析篇) | 应用窥视内核的窗口
  • TypeScript在前端项目的渐进式采用策略
  • C++容器常用集合(附传送门)
  • 基于springboot的校园资料分享平台源码数据库
  • 卷积神经网络(CNN)
  • Linux入门攻坚——22、通信安全基础知识及openssl、CA证书
  • 无障碍Web开发:遵循WCAG标准构建包容性用户体验
  • Isaac Sim 3(学习笔记5.8)
  • 对象定义成final类型还能改变吗
  • Vue Router 路由hash和history模式
  • 【xrframe】优化ar相机中加载模型效果
  • 解决 SyntaxError: Unexpected token ‘.‘ 报错问题
  • 谷歌插件V3知识点
  • webrtc windows 编译,以及peerconnection_client
  • geotrust企业通配符证书2990
  • 网络安全科普:保护你的数字生活
  • Java实战:递归查找指定后缀名的文件
  • Linux 操作系统网络编程1
  • future wait_for()成员、shared_future
  • C++ list介绍(迭代器失效)
  • codeforces 1809C
  • Nginx part3 创建一个https的网站
  • 事件高级。
  • Vue从入门到实战Day04
  • Linux学习笔记:信号
  • C#中的隐式类型转换和显式类型转换
  • linux上如何排查JVM内存过高?
  • 第四届上海理工大学程序设计全国挑战赛 J.上学 题解 DFS 容斥
  • word-排版文本基本格式