题目:假设学校的某学生自习室共有100个位置,自习室门口有一台打卡机。只要有空位,学生就可以进入自习,学生进入时必须在门口打卡登记姓名和进入时间,离开时也要在门口打卡登记离开时间,编程模拟学生进入和离开的过程,要求如下:" (1)学生不能同时使用打卡机; (2)在Linux下编写程序,使用多线程(或多进程)和信号量解决该问题;*(3)动态显示当前的信息(进入者,离开者,剩余座位等)。
时间: 2024-02-26 11:58:55 浏览: 109
自习室学生分布统计系统设计
这是一个经典的多线程编程问题,可以使用多线程和信号量实现。具体实现步骤如下:
1. 定义一个共享内存结构体,用于存储学生进入和离开的信息,包括姓名、进入时间和离开时间等。
2. 定义一个信号量,用于控制打卡机的并发访问。
3. 定义一个线程池,用于处理学生的进入和离开事件。
4. 在主线程中动态显示当前的信息,包括进入者、离开者和剩余座位等。
具体实现可以参考下面的代码(使用C语言和Linux系统):
```c
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>
#define MAX_STUDENT_NUM 100
typedef struct {
char name[20]; // 学生姓名
time_t enter_time; // 进入时间
time_t leave_time; // 离开时间
} Student;
typedef struct {
Student students[MAX_STUDENT_NUM]; // 学生数组
int count; // 当前学生数
} SharedData;
SharedData *shared_data; // 共享内存数据
sem_t sem; // 打卡机信号量
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; // 互斥锁
void *enter(void *arg) {
char *name = (char *)arg;
sem_wait(&sem); // 获取打卡机访问权
pthread_mutex_lock(&mutex); // 获取共享内存访问权
if (shared_data->count < MAX_STUDENT_NUM) {
Student student;
strcpy(student.name, name);
student.enter_time = time(NULL);
shared_data->students[shared_data->count++] = student;
printf("%s 进入了自习室,当前座位数:%d\n", name, MAX_STUDENT_NUM - shared_data->count);
} else {
printf("自习室已满,%s 进入失败\n", name);
}
pthread_mutex_unlock(&mutex); // 释放共享内存访问权
sem_post(&sem); // 释放打卡机访问权
return NULL;
}
void *leave(void *arg) {
char *name = (char *)arg;
sem_wait(&sem); // 获取打卡机访问权
pthread_mutex_lock(&mutex); // 获取共享内存访问权
int i;
for (i = 0; i < shared_data->count; i++) {
if (strcmp(shared_data->students[i].name, name) == 0) {
shared_data->students[i].leave_time = time(NULL);
printf("%s 离开了自习室,停留时间:%ld 秒,当前座位数:%d\n", name,
shared_data->students[i].leave_time - shared_data->students[i].enter_time,
MAX_STUDENT_NUM - shared_data->count + 1);
break;
}
}
if (i == shared_data->count) {
printf("%s 没有进入自习室,无法离开\n", name);
} else {
for (; i < shared_data->count - 1; i++) {
shared_data->students[i] = shared_data->students[i + 1];
}
shared_data->count--;
}
pthread_mutex_unlock(&mutex); // 释放共享内存访问权
sem_post(&sem); // 释放打卡机访问权
return NULL;
}
int main() {
shared_data = (SharedData *)mmap(NULL, sizeof(SharedData), PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
shared_data->count = 0;
sem_init(&sem, 0, 1);
pthread_t tid[MAX_STUDENT_NUM * 2]; // 最多有2倍的线程数
int i;
for (i = 0; i < MAX_STUDENT_NUM * 2; i++) {
if (i % 2 == 0) {
char name[20];
sprintf(name, "学生%d", i / 2 + 1);
pthread_create(&tid[i], NULL, enter, name);
} else {
char name[20];
sprintf(name, "学生%d", i / 2 + 1);
pthread_create(&tid[i], NULL, leave, name);
}
}
while (1) {
sleep(1);
pthread_mutex_lock(&mutex); // 获取共享内存访问权
printf("当前座位数:%d\n", MAX_STUDENT_NUM - shared_data->count);
int i;
for (i = 0; i < shared_data->count; i++) {
printf("%s 进入时间:%ld,离开时间:%ld\n", shared_data->students[i].name,
shared_data->students[i].enter_time, shared_data->students[i].leave_time);
}
pthread_mutex_unlock(&mutex); // 释放共享内存访问权
}
sem_destroy(&sem);
return 0;
}
```
阅读全文