实现一个银行系统该银行设置有M个窗口。每个用户需要先取号只有一台取号机。用户分为对公用户私人用户。私人用户又分为普通用户VIP用户。其中窗口的柜员在服务时按优先级给用户服务其中对公用户的优先级最高VIP用户次之普通用户优先级最低。请使用P、V操作及信号量实现
以下是使用P、V操作及信号量实现银行系统的代码:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#define M 5 // 柜员数
#define N 20 // 最大用户数
// 用户类型
#define PUBLIC 0 // 对公用户
#define VIP 1 // VIP用户
#define NORMAL 2 // 普通用户
sem_t sem_customer; // 顾客信号量
sem_t sem_window[M]; // 柜员信号量
pthread_t tid[N]; // 线程ID数组
int window_status[M] = {0}; // 柜员状态数组
int customer_count = 0; // 顾客数量
int customer_num = 0; // 顾客号码
// 顾客结构体
typedef struct
{
int id; // 顾客号码
int type; // 顾客类型
} customer_t;
// 顾客取号
void get_customer_number(customer_t* customer)
{
sem_wait(&sem_customer); // 等待顾客信号量
customer->id = ++customer_num; // 顾客号码递增
printf("Customer %d got number %d. ", customer->id, customer_num);
switch (customer->type)
{
case PUBLIC:
printf("Type: Public\n");
break;
case VIP:
printf("Type: VIP\n");
break;
case NORMAL:
printf("Type: Normal\n");
break;
}
}
// 顾客排队
void wait_in_line(customer_t customer)
{
int i, window_id;
int priority[M] = {0}; // 每个窗口的优先级
int min_priority = 100; // 最小优先级
for (i = 0; i < M; i++)
{
sem_getvalue(&sem_window[i], &window_status[i]); // 获取柜员信号量的值
if (window_status[i] == 0) // 如果柜员空闲
{
priority[i] = 0; // 优先级为0
}
else
{
switch (customer.type) // 根据顾客类型设置优先级
{
case PUBLIC:
priority[i] = 3;
break;
case VIP:
priority[i] = 2;
break;
case NORMAL:
priority[i] = 1;
break;
}
}
if (priority[i] < min_priority) // 找到最小优先级
{
min_priority = priority[i];
window_id = i;
}
}
sem_wait(&sem_window[window_id]); // 等待柜员信号量
window_status[window_id] = 1; // 将柜员状态设置为忙碌
printf("Customer %d is served by window %d. \n", customer.id, window_id+1);
sleep(3); // 模拟柜员服务时间
window_status[window_id] = 0; // 将柜员状态设置为空闲
sem_post(&sem_window[window_id]); // 释放柜员信号量
}
// 对公用户线程函数
void* public_customer(void* arg)
{
customer_t customer;
customer.type = PUBLIC;
while (1)
{
get_customer_number(&customer);
wait_in_line(customer);
}
return NULL;
}
// VIP用户线程函数
void* vip_customer(void* arg)
{
customer_t customer;
customer.type = VIP;
while (1)
{
get_customer_number(&customer);
wait_in_line(customer);
}
return NULL;
}
// 普通用户线程函数
void* normal_customer(void* arg)
{
customer_t customer;
customer.type = NORMAL;
while (1)
{
get_customer_number(&customer);
wait_in_line(customer);
}
return NULL;
}
int main()
{
int i;
sem_init(&sem_customer, 0, N); // 初始化顾客信号量
for (i = 0; i < M; i++)
{
sem_init(&sem_window[i], 0, 1); // 初始化柜员信号量
}
// 创建对公用户、VIP用户、普通用户线程
pthread_create(&tid[0], NULL, public_customer, NULL);
pthread_create(&tid[1], NULL, vip_customer, NULL);
pthread_create(&tid[2], NULL, normal_customer, NULL);
// 等待线程结束
for (i = 0; i < 3; i++)
{
pthread_join(tid[i], NULL);
}
// 销毁信号量
sem_destroy(&sem_customer);
for (i = 0; i < M; i++)
{
sem_destroy(&sem_window[i]);
}
return 0;
}
``
原文地址: https://www.cveoy.top/t/topic/eyQY 著作权归作者所有。请勿转载和采集!