You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python双教师线程队列的实验作业模拟实现求助

解决多教师并行批改作业的模拟实现问题

你的核心问题是原代码用全局锁强制教师串行工作,且未实现学生排队分配给空闲教师的逻辑。下面是基于queue.Queue实现的正确方案,支持2名教师并行批改,学生自动排队,优先分配给空闲教师:

修改后的完整代码

import threading
import queue
import time
import random
from queue import Queue


class Student:
    def __init__(self, id) -> None:
        self.MIN_TEST_EXECUTION_TIME = 1
        self.MAX_TEST_EXECUTION_TIME = 5
        self._student_id = id
        self.test_execution_time = random.randint(
            self.MIN_TEST_EXECUTION_TIME, self.MAX_TEST_EXECUTION_TIME)
        self._test_result = False

    def get_id(self):
        return self._student_id

    def set_result(self, result: bool):
        if not result:
            print(f"学生 {self.get_id()} 需要重做")
            self.test_execution_time = random.randint(
                self.MIN_TEST_EXECUTION_TIME, self.MAX_TEST_EXECUTION_TIME)
            return
        self._test_result = result

    def take_test(self):
        print(f"学生 {self.get_id()} 开始做作业")
        time.sleep(self.test_execution_time)
        print(f"学生 {self.get_id()} 完成作业,等待批改")

    def get_result(self):
        return self._test_result


class Students:
    def __init__(self):
        self._students = []

    def _append_student(self, student_id):
        self._students.append(Student(student_id))

    def create_group(self, students_amount):
        for _ in range(students_amount):
            self._append_student(f'#{_+1}')  # 学号从#1开始更直观

    def get_group(self):
        return self._students


class Teacher:
    def __init__(self, name) -> None:
        self.name = name
        self.MIN_TEST_CHECKING_TIME = 1
        self.MAX_TEST_CHECKING_TIME = 5

    def check_test(self, student: Student):
        check_time = random.randint(self.MIN_TEST_CHECKING_TIME, self.MAX_TEST_CHECKING_TIME)
        print(f"教师 {self.name} 开始批改学生 {student.get_id()} 的作业")
        time.sleep(check_time)
        print(f"教师 {self.name} 完成学生 {student.get_id()} 的作业批改")
        result = random.choice([True, False])
        student.set_result(result)


class Exam:
    def __init__(self, teachers: list, tested: Students) -> None:
        self.teachers = teachers
        self.students = tested.get_group()
        self.submission_queue = Queue()  # 作业提交队列
        self.completed_students = 0
        self.total_students = len(self.students)
        self.lock = threading.Lock()  # 统计完成人数的锁

    def teacher_work(self, teacher):
        # 教师持续从队列取作业批改,直到收到结束信号
        while True:
            student = self.submission_queue.get()
            if student is None:  # None作为结束信号
                break
            teacher.check_test(student)
            if student.get_result():
                with self.lock:
                    self.completed_students += 1
                print(f"学生 {student.get_id()} 通过考核")
            else:
                # 重做后重新提交队列
                threading.Thread(target=self.student_work, args=(student,)).start()
            self.submission_queue.task_done()

    def student_work(self, student):
        # 学生完成作业后提交到队列
        student.take_test()
        self.submission_queue.put(student)

    def run_test(self):
        # 启动所有教师线程
        teacher_threads = []
        for teacher in self.teachers:
            t = threading.Thread(target=self.teacher_work, args=(teacher,))
            teacher_threads.append(t)
            t.start()

        # 启动所有学生线程,同时开始做作业
        student_threads = []
        for student in self.students:
            t = threading.Thread(target=self.student_work, args=(student,))
            student_threads.append(t)
            t.start()

        # 等待所有学生完成(包括重做)
        while True:
            with self.lock:
                if self.completed_students == self.total_students:
                    break
            time.sleep(0.5)

        # 给每个教师发送结束信号
        for _ in self.teachers:
            self.submission_queue.put(None)

        # 等待所有教师线程结束
        for t in teacher_threads:
            t.join()

        print("所有学生完成考核,考试结束")


if __name__ == "__main__":
    studs = Students()
    studs.create_group(20)

    teachers = [Teacher("张老师"), Teacher("李老师")]

    exam = Exam(teachers, studs)
    exam.run_test()

关键改动说明

  1. 作业提交队列:用queue.Queue实现学生作业的排队,学生完成作业后将自己放入队列,教师线程从队列中取任务,自动实现"空闲教师优先处理"的逻辑(Queue的FIFO特性+多线程取任务,空闲的教师会先拿到队列中的学生)。
  2. 教师独立线程:每个教师启动一个独立线程,持续从队列取学生批改,直到收到None结束信号,实现教师并行工作。
  3. 学生重做逻辑:学生未通过时,重新启动一个线程执行做作业+提交队列的流程,直到通过。
  4. 完成状态统计:用锁保护completed_students变量,确保多线程下统计准确,当所有学生都通过后,给教师发送结束信号,等待教师线程收尾。
  5. 去掉全局锁:原代码的全局锁导致教师串行工作,现在改为队列自动调度,教师线程无需全局锁,真正实现并行批改。

内容的提问来源于stack exchange,提问作者cherry_ds

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 07:52:53