题目:假设学校的某学生自习室共有 100 个位置,自习室门口有一台打卡机。只要有空位。 学生就可以进入自习,学生进入时必须在门口打卡登记姓名和进入时间,离开时也要在门口 打卡登记离开时问,编程模拟学生进入和离开的过程,要求如下: (1) 学生不能同时使用打卡机A。 (2) 在Linux下编写程序,使用多线程 (或多进程)和信号量解决该问题,。 (3) 动态显示当前的信息 (进入者,离开者,剩余座位等)。用c编写
时间: 2024-02-26 20:57:56 浏览: 17
好的,以下是使用 C 语言实现的代码:
```c
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>
#include <time.h>
#define MAX_SEATS 100 // 自习室最大座位数
char *seats[MAX_SEATS]; // 学生座位信息
sem_t sema; // 打卡机信号量
void *student(void *param) {
char *name = (char *)param;
time_t enter_time, leave_time;
int seat = -1;
// 进入自习室
time(&enter_time);
sem_wait(&sema);
for (int i = 0; i < MAX_SEATS; i++) {
if (seats[i] == NULL) {
seat = i;
seats[i] = name;
break;
}
}
if (seat >= 0) {
printf("%s 进入自习室,座位号为 %d,进入时间为 %s\n", name, seat, ctime(&enter_time));
} else {
printf("%s 进入自习室失败,座位已满。\n", name);
sem_post(&sema);
return NULL;
}
sem_post(&sema);
// 离开自习室
sleep(rand() % 10 + 1);
sem_wait(&sema);
seats[seat] = NULL;
time(&leave_time);
printf("%s 离开自习室,座位号为 %d,离开时间为 %s\n", name, seat, ctime(&leave_time));
sem_post(&sema);
return NULL;
}
int main() {
// 初始化座位信息和信号量
for (int i = 0; i < MAX_SEATS; i++) {
seats[i] = NULL;
}
sem_init(&sema, 0, 1);
// 创建 200 个学生线程
pthread_t students[200];
for (int i = 0; i < 200; i++) {
char *name = (char *)malloc(sizeof(char) * 10);
sprintf(name, "学生%d", i);
pthread_create(&students[i], NULL, student, name);
}
// 不断输出剩余座位信息
while (1) {
sleep(5);
sem_wait(&sema);
int occupied = 0;
for (int i = 0; i < MAX_SEATS; i++) {
if (seats[i] != NULL) {
occupied++;
}
}
printf("现在共有 %d 个座位,已占用 %d 个座位,剩余 %d 个座位。\n", MAX_SEATS, occupied, MAX_SEATS - occupied);
sem_post(&sema);
}
return 0;
}
```
在上面的代码中,我们定义了一个 `student` 函数,它代表一个学生线程,会先尝试进入自习室,如果有空位就进入,并在门口打卡登记姓名和进入时间。如果没有空位就进入失败。然后,它会在自习室内学习一段时间后离开,并在门口打卡登记离开时间。
我们还定义了一个信号量 `sema`,它的初始值为 1,代表打卡机只能同时被一个学生使用。每个学生线程在进入和离开自习室时都要先获得 `sema` 的锁,以保证打卡机的互斥使用。
最后,我们在主函数中不断输出剩余座位信息。这里的输出不是必需的,只是为了动态显示当前的信息,方便观察程序的运行状态。