假设学校的某学生自习室共有100个位置,自习室门口有一台打卡机。只要有空位,学生就可以进入自习,学生进入必须在门口打卡登记姓名和进入时间,离开时也要在门口打卡登记离开时间,编程模拟学生进入和离开的过程,要求如下:1.学生不能同时使用打卡机;2.在Linux下编写程序,使用多线程(或多进程)和信号量解决问题;3.动态显示当前的消息(进入者,离开者,剩余座位等)用c语言编写
时间: 2024-02-26 07:58:59 浏览: 123
自习室学生分布统计系统设计
好的,这是一个比较典型的多线程和信号量的应用场景,下面是代码实现:
```c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <semaphore.h>
#define TOTAL_SEATS 100
#define MAX_STUDENTS 200
// 定义学生结构体
typedef struct student {
char name[20]; // 姓名
int enter_time; // 进入时间
int leave_time; // 离开时间
} Student;
Student students[MAX_STUDENTS]; // 存储所有学生信息
int num_students = 0; // 学生总数
sem_t mutex; // 信号量,用于保证打卡机不会同时被多个学生使用
sem_t seats; // 信号量,用于控制剩余座位数
void *enter(void *arg); // 进入自习室
void *leave(void *arg); // 离开自习室
void print_info(); // 打印当前状态信息
int main() {
sem_init(&mutex, 0, 1); // 初始化信号量
sem_init(&seats, 0, TOTAL_SEATS);
pthread_t tids[MAX_STUDENTS]; // 存储所有线程ID
int i, ret;
// 创建学生线程
for (i = 0; i < MAX_STUDENTS; i++) {
ret = pthread_create(&tids[i], NULL, enter, (void *)(long)i);
if (ret != 0) {
printf("Create thread error!\n");
return -1;
}
usleep(rand() % 1000); // 随机等待一段时间
}
// 等待所有学生进入自习室
for (i = 0; i < MAX_STUDENTS; i++) {
pthread_join(tids[i], NULL);
}
// 创建学生线程
for (i = 0; i < num_students; i++) {
ret = pthread_create(&tids[i], NULL, leave, (void *)(long)i);
if (ret != 0) {
printf("Create thread error!\n");
return -1;
}
usleep(rand() % 1000); // 随机等待一段时间
}
// 等待所有学生离开自习室
for (i = 0; i < num_students; i++) {
pthread_join(tids[i], NULL);
}
sem_destroy(&mutex); // 销毁信号量
sem_destroy(&seats);
return 0;
}
void *enter(void *arg) {
int id = (int)(long)arg;
sem_wait(&seats); // 等待剩余座位
sem_wait(&mutex); // 等待打卡机
sprintf(students[id].name, "Student-%d", id);
students[id].enter_time = time(NULL);
num_students++;
print_info(); // 打印当前状态信息
sem_post(&mutex); // 释放打卡机
return NULL;
}
void *leave(void *arg) {
int id = (int)(long)arg;
sem_wait(&mutex); // 等待打卡机
students[id].leave_time = time(NULL);
num_students--;
print_info(); // 打印当前状态信息
sem_post(&mutex); // 释放打卡机
sem_post(&seats); // 释放座位
return NULL;
}
void print_info() {
int i;
system("clear"); // 清屏
printf("Total seats: %d\n", TOTAL_SEATS);
printf("Remaining seats: %d\n", sem_getvalue(&seats, NULL));
printf("Number of students in the room: %d\n", num_students);
printf("Name\tEnter Time\tLeave Time\n");
for (i = 0; i < num_students; i++) {
printf("%s\t%d\t\t%d\n", students[i].name, students[i].enter_time, students[i].leave_time);
}
}
```
代码中使用了两个信号量:`mutex` 用于保证打卡机不会同时被多个学生使用,`seats` 用于控制剩余座位数。每个学生都是一个线程,进入自习室时会等待剩余座位,然后再等待打卡机,打卡完成后就可以占用一个座位。离开自习室时会等待打卡机,打卡完成后就可以释放座位。同时使用 `pthread_join()` 函数等待所有线程执行完毕,最终销毁信号量。
阅读全文