C语言演示多线程编程条件下自旋锁和屏障的使用

主线故事:

有4个人玩游戏输了,惩罚:

1 分别使用4台不同的ATM机给我存钱

2 必须一块一块的存

3 存完还得在ATM上看一下我的余额

设计模式:

1 每个人使用一条单独的线程,再准备一个计时线程用来输出时间

2 存钱 涉及到 对共享资源的读写,是原子操作需要用锁保护 这里使用自旋锁

3 都存完钱后需要等待 在各自的ATM上回显余额 这里使用屏障技术

4 如果在主线程中回显 对应他们给我打电话告诉我存完了 我自己看一下 则不需要使用屏障

   因为  join保证了 我查看是在所有操作都完成的情况下进行的

运行环境:

unix-like系统 或 GNU_C库 或 同等条件 可以在IDE集成环境下也可以编译后在终端单独运行

进程持续1分钟以内

#define _GNU_SOURCE
#include <pthread.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <string.h>
#include <stdlib.h>
#include <sys/msg.h>
#include <time.h>pthread_spinlock_t spinlock;
pthread_barrier_t barrier;
// 这是被cancel的时间显示线程的清理函数
void cleanup_func(void *p)
{printf("%ld pthread_exit\n", pthread_self());
}
// 用于显示时间的线程
void *get_time(void *p)
{// 注册清理函数pthread_cleanup_push(cleanup_func, NULL);// 每隔1秒显示当前时间while (1){time_t rawtime;struct tm *info;char buffer[128];time(&rawtime);info = localtime(&rawtime);strftime(buffer, 128, "%H:%M:%S", info);printf("%s\n", buffer);sleep(1);}pthread_cleanup_pop(1);pthread_exit(NULL);
}
// 用于回显余额
void balance_echo()
{char buf[128] = {0};// 打开int fd = open("account_balance", O_RDWR);// 读pread(fd, buf, 128, 0);// 打印在stdoutprintf("卡内余额:$%s\n", buf);// 关闭close(fd);
}
// 用于处理每台ATM不同的存钱逻辑
void atm_handler(int serial_number)
{char buf[128] = {0};int fd = open("account_balance", O_RDWR);// 储蓄序列号乘以500000的钱int count = serial_number * 500000;// 上自旋锁pthread_spin_lock(&spinlock);// 读取余额pread(fd, buf, 128, 0);// 字符串转整数long long ab = strtoll(buf, NULL, 10);for (size_t i = 0; i < count; i++){// 一块一块加,测试自旋锁是不是好使ab += 1;// 写入buf,整数转字符串snprintf(buf, 128, "%lld", ab);// 写入余额文件pwrite(fd, buf, strlen(buf), 0);}// 解自旋锁pthread_spin_unlock(&spinlock);close(fd);
}
void *spinlock_in_barrier(void *p)
{// void*标准转整 便于使用int num = *((int *)p);// 调用ATM储蓄逻辑atm_handler(num);// 当某线程到达屏障点时输出printf("%ld 到达了屏障点\n", pthread_self());// 等4个储蓄线程全到pthread_barrier_wait(&barrier);// 每个线程在自己的ATM显示屏上查询余额,而不是在主线程中balance_echo();// 线程结束printf("%ld pthread_exit\n", pthread_self());pthread_exit(NULL);
}void account_balance_init()
{// 如果该文件存在就删除if (access("account_balance", F_OK) == 0){remove("account_balance");}// 创建文件且有读写权限int fd = open("account_balance", O_RDWR | O_CREAT, 0700);// 卡内初始余额就是5块钱char buf[8] = "5";write(fd, buf, strlen(buf));close(fd);
}
// 创建1个计时线程,4个ATM线程并回收他们
void create_join_pthread()
{pthread_t tids[5] = {0};int i;// ATM的序列号,表示不同的ATM,存不同数额的钱int arr[5] = {0, 2, 4, 6, 8};pthread_create(&tids[0], NULL, get_time, NULL);for (i = 1; i < 5; i++){pthread_create(&tids[i], NULL, spinlock_in_barrier, &arr[i]);}for (i = 1; i < 5; i++){pthread_join(tids[i], NULL);printf("%lu join\n", tids[i]);}// 当4条ATM线程都返回时,回收计时线程if (pthread_cancel(tids[0])){perror("cancel");}pthread_join(tids[0], NULL);printf("%lu join\n", tids[0]);
}
int main()
{// 初始化账户余额文件 ,设为5块钱account_balance_init();// 初始化自旋锁pthread_spin_init(&spinlock, PTHREAD_PROCESS_PRIVATE);// 初始化屏障,设为需要触发4次pthread_barrier_init(&barrier, NULL, 4);// 创建及回收5条线程create_join_pthread();// 销毁自旋锁pthread_spin_destroy(&spinlock);// 销毁屏障pthread_barrier_destroy(&barrier);return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/738395.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

windows下安装python virtualenv 虚拟环境

1、首先验证 python 是否安装成功 python -V Python 3.8.2如果出现版本号&#xff0c;表示安装成功了 2、通过 pip 安装 virtualenv pip install virtualenv3、创建虚拟环境 C:\Users\capitek-fengxl> mkvirtualenv blog # 激活虚拟环境 C:\Users\capitek-fengxl> …

SQL 优化实践:关于增强 OceanBase本地索引性能的案例

本文通过一个案例&#xff0c;帮用户了解在Oracle迁移Oceanbase时&#xff0c;应该如何选择全局索引和本地索引以带来更好的SQL性能。 作者&#xff1a;胡呈清&#xff0c;爱可生的DBA团队成员&#xff0c;擅长故障分析和性能优化。本文约 5000 字&#xff0c;预计阅读需要 15 …

GPT实战系列-LangChain实现简单链

GPT实战系列-LangChain实现简单链 LangChain GPT实战系列-LangChain如何构建基通义千问的多工具链 GPT实战系列-构建多参数的自定义LangChain工具 GPT实战系列-通过Basetool构建自定义LangChain工具方法 GPT实战系列-一种构建LangChain自定义Tool工具的简单方法 GPT实战系…

Qt/QML编程之路:fork、vfork、exec、clone的对比及使用(46)

前言: 系统调用system call是OS提供的服务提供接口。系统调用fork()、vfork()、exec()和clone()都用于创建和操作进程。Linux下Qt编程也会用到vfork进行多进程间通信。让我们看一下以下每个系统调用的概述和比较: fork()、vfork()和clone()的工作原理相似,但在处…

「jQuery系列」jQuery DOM操作/尺寸

文章目录 一、jQuery DOM操作元素选择元素创建元素插入元素删除元素复制属性操作文本和 HTML 内容操作CSS 类操作遍历 DOM 二、jQuery 尺寸案例一&#xff1a;获取元素尺寸案例二&#xff1a;设置元素尺寸案例三&#xff1a;使用内外尺寸方法 三、热门文章 一、jQuery DOM操作 …

【Vue】.sync 修饰符作用

文章目录 基本用法 基本用法 官方文档是这样介绍的&#xff1a;.sync 修饰符 简单来说就是实现父子组件数据之间的双向绑定&#xff0c;当子组件修改了一个 props 的值时&#xff0c;也会同步到父组件中&#xff0c;实现子组件同步修改父组件&#xff0c;与v-model类似。类别在…

计算机网络面经八股-什么是 SYN洪泛攻击?如何防范?

SYN洪泛攻击属于 DOS 攻击的一种&#xff0c;它利用 TCP 协议缺陷&#xff0c;通过发送大量的半连接请求&#xff0c;耗费 CPU 和内存资源。 原理&#xff1a; 在三次握手过程中&#xff0c;服务器发送 [SYN/ACK] 包&#xff08;第二个包&#xff09;之后、收到客户端的 [ACK…

狂飙Linux平台,PostgreSQL16部署大全

&#x1f4e2;&#x1f4e2;&#x1f4e2;&#x1f4e3;&#x1f4e3;&#x1f4e3; 哈喽&#xff01;大家好&#xff0c;我是【IT邦德】&#xff0c;江湖人称jeames007&#xff0c;10余年DBA及大数据工作经验 一位上进心十足的【大数据领域博主】&#xff01;&#x1f61c;&am…

VUE学习第三篇----VUE实例

1、当一个 Vue 实例被创建时&#xff0c;它将 data 对象中的所有的 property 加入到 Vue 的响应式系统中。当这些 property 的值发生改变时&#xff0c;视图将会产生“响应”&#xff0c;即匹配更新为新的值。 html网页文件如下所示&#xff1a; <html> <head> &…

CSS note

文章目录 CSS docCSS 盒子模型微信小程序 WXSSrpx: responsive pixel. 规定屏幕宽度为 750 rpx样式导入引用外部样式 内联样式选择器CSS 语法列举排版 CSS doc https://www.w3schools.com/cssref/pr_class_position.php https://www.w3schools.com/css/tryit.asp?filenametry…

JavaSE——面向对象高级一(3/4)-面向对象三大特征之二:继承(初步认识继承、了解继承的好处)

目录 认识继承 继承的好处 认识继承 什么是继承&#xff1f; Java中提供了一个关键字extends&#xff0c;用这个关键字&#xff0c;可以让一个类和另一个类建立起父子关系。 例如&#xff1a; public class B extends A{} 此时A类就称为父类&#xff08;基类或超类&…

MySQL Connector连接失败之SSL connection error: protocol version mismatch

调用 mysql_real_connect&#xff08;&#xff09; 连接失败&#xff0c;报错为ERROR 2026 (HY000): SSL connection error: protocol version mismatch 调用mysql_error&#xff08;&#xff09;查看失败原因&#xff0c;结果为 SSL connection error: protocol version …

人口性别年龄分布数据、不同年龄结构、性别结构人口分布数据、乡镇街道人口分布数据

人口分布是指人口在一定时间内的空间存在形式、分布状况&#xff0c;包括各类地区总人口的分布&#xff0c;以及某些特定人口&#xff08;如城市人口、、特定的人口过程和构成&#xff08;如迁移、性别等&#xff09;的分布等。 人口分布的最大特征是不平衡性。就全世界而言&am…

mysql 替换空值

函数 IFNULL() 用于判断一个表达式时否为NULL,如果为 NULL 则返回指定的代替值&#xff0c;否则返回原表达式的值。 函数&#xff1a; IFNULL(expression,alternavicate_value) expression 要判断的表达式alternavicate_value 当表达式为 NULL时要返回的代替值

Kafka整理-Consumer(消费者)

在Apache Kafka中,消费者(Consumer)是负责从Kafka的主题(Topics)读取数据的客户端应用程序。Kafka消费者的主要特点和工作原理如下: 主要特点 1、订阅主题: 消费者可以订阅一个或多个Kafka主题,并从中读取数据。2、消费者群组(Consumer Groups): 消费者可以组成消费…

Edu12 Beautiful Subarrays --- 题解

Beautiful Subarrays&#xff1a; 题目大意: 思路解析&#xff1a; 要找到一个区间并且区间的l--r里面所有的元素异或值大于等于k&#xff0c;称这样的数组是优美子数组&#xff0c;问优美子数组有多少个。 [L,R] 的数组异或和等价于 (a1,a2,a3,....aL-1) ^ (a1,a2,a3,a4,..…

CompletionService 处理异步任务

案例: public static void main(String[] args) throws Exception {ExecutorService executorService Executors.newCachedThreadPool();ArrayList<Future<Integer>> list new ArrayList<>();Future<Integer> future_15 executorService.submit(()…

【2024金三银四】

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学习,不断总结,共同进步,活到老学到老导航 檀越剑指大厂系列:全面总结 jav…

不锈钢电阻器-栅极电阻器 - 为什么要使用它们呢?

常规 如果你看一个典型的吉他放大器的原理图&#xff0c;你会注意到有一个电阻器与第一个电子管的栅极串联&#xff0c;通常在68K左右&#xff0c;还有一个电阻器与功率管的栅极串联&#xff0c;通常为1.5K或5.6K&#xff0c;你可能会偶尔看到非常大的电阻&#xff0c; 例如 4…

ssm+vue的高校课程评价系统(有报告)。Javaee项目,ssm vue前后端分离项目。

演示视频&#xff1a; ssmvue的高校课程评价系统&#xff08;有报告&#xff09;。Javaee项目&#xff0c;ssm vue前后端分离项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构&…