Python线程同步问题求助:continue_program执行时需锁定其他方法
Python线程同步问题解决方案
问题分析
你的代码存在以下核心问题:
- 定义了
threading.Lock但未实际使用,导致continue_program执行时其他线程仍能继续运行 - 共享变量
self.flag的读写未加同步,存在线程可见性问题 socket.accept()是阻塞调用,即使self.flag被设为False,主线程会卡在该调用上无法及时退出continue_program中仅处理yes/y和其他情况,但未通过锁机制阻塞其他方法
修改后的代码
import socket import threading class Server: def __init__(self, host, port): self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # 设置socket超时,避免accept永久阻塞 self.server.settimeout(1) self.host = host self.port = port self.flag = True self.locker = threading.Lock() def start_server(self): self.server.bind((self.host, self.port)) self.server.listen(5) print("Created the server") while self.flag: # 尝试获取锁,只有当continue_program执行完毕释放锁后才能继续 with self.locker: if not self.flag: break print("Waiting when client connects") try: client, _ = self.server.accept() except socket.timeout: continue print("Client connected") # 处理客户端的线程启动时不持有锁,避免阻塞其他操作 t = threading.Thread(target=self.handle_client, args=(client,)) t.start() # 关闭服务器socket self.server.close() print("Server stopped") def handle_client(self, client): while self.flag: # 每次接收数据前检查锁和flag with self.locker: if not self.flag: break try: data = client.recv(4096) except Exception as e: print(f"Client error: {e}") break if not data: print("Client disconnected") break data = data.decode("utf-8") print(f"Data received: \n{data}") # 调用continue_program时持有锁,阻塞其他需要锁的方法 with self.locker: self.continue_program() # 执行完后检查flag,若为False则退出循环 if not self.flag: break client.close() def continue_program(self): con_inp = input("Continue(yes,no)?: ") if con_inp.lower() in ["yes", "y"]: return # 所有非yes/y的输入都设置flag为False self.flag = False if __name__ == "__main__": obj_server = Server("127.0.0.1", 8080) obj_server.start_server()
关键修改说明
锁的正确使用:
start_server的循环中用with self.locker包裹accept操作,确保continue_program执行时主线程无法继续等待新客户端handle_client调用continue_program时持有锁,此时start_server会被阻塞,直到锁被释放continue_program在锁保护下修改self.flag,避免多线程竞态
解决socket阻塞问题:
- 给服务器socket设置1秒超时,
accept每隔1秒返回一次超时异常,循环中可及时检查self.flag状态并退出
- 给服务器socket设置1秒超时,
线程安全的flag处理:
- 所有对
self.flag的读写都在锁的保护下,保证线程可见性和操作原子性
- 所有对
输入逻辑优化:
- 无论输入
no/n还是其他内容,都会将self.flag设为False,确保服务器能及时停止
- 无论输入
内容的提问来源于stack exchange,提问作者clqwnless
相关产品推荐
相关产品推荐

