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

Linux程序开发(十二):线程与多线程同步互斥实现抢票系统

Tips:"分享是快乐的源泉💧,在我的博客里,不仅有知识的海洋🌊,还有满满的正能量加持💪,快来和我一起分享这份快乐吧😊!

喜欢我的博客的话,记得点个红心❤️和小关小注哦!您的支持是我创作的动力!数据源存放在我的资源下载区啦!

Linux程序开发(十二):线程与多线程同步互斥实现抢票系统

目录

  • Linux程序开发(十二):线程与多线程同步互斥实现抢票系统
    • 题目:抢票系统
    • 题目描述:
    • 示例输入:
    • 示例输出:
    • 提示:
    • 解答:
    • 截图:

题目:抢票系统

题目描述:

某公司的演唱会门票正在热销中,为了让用户更好地体验购票过程,公司决定开启一个抢票系统。具体来说,用户可以在系统中选择想要购买的门票数量,系统会随机生成几个购票请求,并给出这些请求的优先级(优先级越高,越先处理)。每个请求需要购买一定数量的门票,如果门票数量已经不足,则该请求将会被拒绝。如果多个请求同时到达,需要按照优先级进行处理。在处理完一个请求后,系统需要输出当前剩余的门票数量。

请你使用Linux下的线程和多线程同步互斥知识,编写一个C程序实现这个抢票系统,要求满足以下条件:
1、系统需要启动两个线程,一个线程代表用户,另一个线程代表抢票程序。
2、用户可以通过命令行输入想要购买的门票数量,抢票程序会自动生成随机的购票请求,并给出优先级。
3、抢票程序需要使用线程池来处理请求,每个请求需要分配一个线程来处理。
4、抢票程序需要使用信号量和互斥锁等机制来实现线程间同步和互斥访问共享资源(如门票数量)。
5、在处理完每个请求后,抢票程序需要输出当前剩余的门票数量。
6、当所有的门票售出后,抢票程序需要结束运行。

示例输入:

请输入购票数量:10

示例输出:

当前剩余门票数量:90
当前剩余门票数量:85
当前剩余门票数量:75
当前剩余门票数量:70
当前剩余门票数量:65
当前剩余门票数量:60
当前剩余门票数量:53
当前剩余门票数量:48
当前剩余门票数量:38

提示:

可以使用Linux系统函数pthread_create()、pthread_join()、pthread_mutex_init()、pthread_mutex_lock()、pthread_mutex_unlock()和pthread_mutex_destroy()来创建和使用线程和互斥锁。
可以使用Linux系统函数sem_init()、sem_wait()、sem_post()和sem_destroy()来创建和使用信号量。

解答:

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <time.h>
#include <semaphore.h>#define TOTAL_TICKETS 100// 定义全局变量和互斥锁、信号量
int tickets = TOTAL_TICKETS;
pthread_mutex_t mutex;
sem_t semaphore;// 定义线程池结构体
typedef struct {int priority;int num_tickets;
} Request;void* user_thread(void* arg) {// 输入购票数量int num_tickets;printf("请输入购票数量:");scanf("%d", &num_tickets);// 等待抢票线程结束struct timespec delay = {0, 500000000};  // 500msclock_nanosleep(CLOCK_MONOTONIC, 0, &delay, NULL);// 创建抢票请求Request* request = (Request*)malloc(sizeof(Request));request->priority = 0;  // 用户请求的优先级为最高request->num_tickets = num_tickets;// 抢票程序处理请求pthread_mutex_lock(&mutex);if (tickets >= num_tickets) {tickets -= num_tickets;printf("购票成功!当前剩余门票数量:%d\n", tickets);} else {printf("购票失败!当前剩余门票数量:%d\n", tickets);}pthread_mutex_unlock(&mutex);free(request);return NULL;
}void* ticket_thread(void* arg) {Request* request = (Request*)arg;// 模拟处理请求的耗时操作struct timespec delay = {request->priority, 0};clock_nanosleep(CLOCK_MONOTONIC, 0, &delay, NULL);sem_wait(&semaphore);  // 请求抢到票之前等待信号量pthread_mutex_lock(&mutex);if (tickets >= request->num_tickets) {tickets -= request->num_tickets;printf("当前剩余门票数量:%d\n", tickets);} else {printf("请求被拒绝!当前剩余门票数量:%d\n", tickets);}pthread_mutex_unlock(&mutex);sem_post(&semaphore);  // 抢到票后释放信号量free(request);return NULL;
}
int main() {// 初始化互斥锁和信号量pthread_mutex_init(&mutex, NULL);sem_init(&semaphore, 0, 1);// 创建线程池pthread_t threads[10];// 创建抢票线程for (int i = 0; i < 10; i++) {Request* request = (Request*)malloc(sizeof(Request));request->priority = rand() % 10 + 1;  // 随机生成优先级request->num_tickets = rand() % 10 + 1;  // 随机生成购票数量pthread_create(&threads[i], NULL, ticket_thread, request);struct timespec delay = {0, 50000000};  // 50msclock_nanosleep(CLOCK_MONOTONIC, 0, &delay, NULL); // 睡眠一段时间,防止随机数相同}// 创建用户线程pthread_t user_tid;pthread_create(&user_tid, NULL, user_thread, NULL);// 等待抢票线程结束for (int i = 0; i < 10; i++) {pthread_join(threads[i], NULL);}// 等待用户线程结束pthread_join(user_tid, NULL);// 清理资源pthread_mutex_destroy(&mutex);sem_destroy(&semaphore);return 0;
}

截图:

在这里插入图片描述
图 3.1 运行结果图

相关文章:

  • 【单片机】STM32F070F6P6 开发指南(一)STM32建立HAL工程
  • VUE2 tab切换导航 展示页面内容(父级子级独立)
  • c语言:模拟strlen(三种方法)最全版本
  • Day03—flask与react实现交互(解决跨域问题)
  • 从容应对亿级QPS访问,Redis还缺少什么?no.29
  • c语言----函数
  • 中间件的概念及示例
  • Android跨进程通信--Binder机制及AIDL是什么?
  • 详解 Cookies 和 WebStorage
  • 软件测试面试题(四)
  • 【经典论文阅读10】MNS采样——召回双塔模型的最佳拍档
  • ffpmeg windows WSl 编译so
  • 【开源】大学生竞赛管理系统 JAVA+Vue+SpringBoot+MySQL
  • leedcode【142】. 环形链表 II——Java解法
  • K8s的常用命令以及yaml文件的创建
  • “寒冬”下的金三银四跳槽季来了,帮你客观分析一下局面
  • flask接收请求并推入栈
  • git 常用命令
  • Material Design
  • Median of Two Sorted Arrays
  • miniui datagrid 的客户端分页解决方案 - CS结合
  • node 版本过低
  • Odoo domain写法及运用
  • PHP变量
  • Python打包系统简单入门
  • webpack入门学习手记(二)
  • 阿里中间件开源组件:Sentinel 0.2.0正式发布
  • 机器学习中为什么要做归一化normalization
  • 基于组件的设计工作流与界面抽象
  • 强力优化Rancher k8s中国区的使用体验
  • 收藏好这篇,别再只说“数据劫持”了
  • #调用传感器数据_Flink使用函数之监控传感器温度上升提醒
  • #我与Java虚拟机的故事#连载08:书读百遍其义自见
  • (Spark3.2.0)Spark SQL 初探: 使用大数据分析2000万KF数据
  • (二)原生js案例之数码时钟计时
  • (官网安装) 基于CentOS 7安装MangoDB和MangoDB Shell
  • (亲测有效)推荐2024最新的免费漫画软件app,无广告,聚合全网资源!
  • (原創) X61用戶,小心你的上蓋!! (NB) (ThinkPad) (X61)
  • ******之网络***——物理***
  • ****三次握手和四次挥手
  • .NET Core 控制台程序读 appsettings.json 、注依赖、配日志、设 IOptions
  • .Net OpenCVSharp生成灰度图和二值图
  • .net wcf memory gates checking failed
  • .NET 反射 Reflect
  • .NET 中创建支持集合初始化器的类型
  • .NET/MSBuild 中的发布路径在哪里呢?如何在扩展编译的时候修改发布路径中的文件呢?
  • .NET导入Excel数据
  • .NET开源项目介绍及资源推荐:数据持久层
  • .考试倒计时43天!来提分啦!
  • @RequestMapping 的作用是什么?
  • @Validated和@Valid校验参数区别
  • [3300万人的聊天室] 作为产品的上游公司该如何?
  • [C++] vector对比list deque的引出
  • [error] 17755#0: *58522 readv() failed (104: Connection reset by peer) while reading upstream
  • [FTP]pureftp部署和优化