题目:假设学校的某学生自习室共有 100 个位置,自习室门口有一台打卡机。只要有空位。 学生就可以进入自习,学生进入时必须在门口打卡登记姓名和进入时间,离开时也要在门口 打卡登记离开时问,编程模拟学生进入和离开的过程,要求如下: (1) 学生不能同时使用打卡机A。 (2) 在Limuz下编马程序,使用多线程 《或多进程)和信号量解决该问题,。 (3) 动态显示当前的信息 (进入者,离开者,剩余座位等)。
时间: 2024-02-26 22:57:46 浏览: 21
好的,我理解了你的问题。这是一个典型的多线程问题,可以使用 Python 的 threading 库来实现。以下是一个简单的实现:
```python
import threading
import time
import random
MAX_SEATS = 100 # 自习室最大座位数
seats = [] # 学生座位信息
for i in range(MAX_SEATS):
seats.append(None)
class Student(threading.Thread):
def __init__(self, name):
threading.Thread.__init__(self)
self.name = name
def run(self):
global seats
# 进入自习室
enter_time = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())
with sema:
seat = None
for i, s in enumerate(seats):
if s is None:
seat = i
seats[i] = self.name
break
if seat is not None:
print(f"{self.name} 进入自习室,座位号为 {seat},进入时间为 {enter_time}。")
else:
print(f"{self.name} 进入自习室失败,座位已满。")
return
# 离开自习室
time.sleep(random.randint(1, 10))
with sema:
seats[seat] = None
leave_time = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())
print(f"{self.name} 离开自习室,座位号为 {seat},离开时间为 {leave_time}。")
# 打卡机信号量
sema = threading.Semaphore(1)
# 启动 200 个学生线程
for i in range(200):
s = Student(f"学生{i}")
s.start()
# 不断输出剩余座位信息
while True:
time.sleep(5)
with sema:
occupied = sum([1 for s in seats if s is not None])
print(f"现在共有 {MAX_SEATS} 个座位,已占用 {occupied} 个座位,剩余 {MAX_SEATS - occupied} 个座位。")
```
在上面的代码中,我们定义了一个 `Student` 类,每个 `Student` 实例代表一个学生,它会先尝试进入自习室,如果有空位就进入,并在门口打卡登记姓名和进入时间。如果没有空位就进入失败。然后,它会在自习室内学习一段时间后离开,并在门口打卡登记离开时间。
我们还定义了一个信号量 `sema`,它的初始值为 1,代表打卡机只能同时被一个学生使用。每个学生线程在进入和离开自习室时都要先获得 `sema` 的锁,以保证打卡机的互斥使用。
最后,我们在主线程中不断输出剩余座位信息。这里的输出不是必需的,只是为了动态显示当前的信息,方便观察程序的运行状态。