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

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

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

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};  // 500ms
    clock_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};  // 50ms
        clock_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 运行结果图

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

卡林神不是猫

如果您觉得有帮助可以鼓励小卡哦

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值