如何在Python中杀死服务器线程



我有一个应用程序,它运行多个服务器,所有服务器都在自己的线程上。我希望能够告诉线程停止运行。不过,要做到这一点,我需要告诉线程停止,然后线程需要告诉服务器停止,然后服务器关闭自己的套接字(它处于接收循环中,从所有连接的客户端获取数据(。我该怎么做?

我尝试过使用传递的停止变量,但我认为问题出在需要关闭的套接字上。我找不到一种方法来告诉服务器关闭套接字,而不直接向服务器发送消息告诉它这样做,这似乎效率很低。

这是我的服务器代码:

import socket
import threading
class Server:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connections = []
def __init__(self, port):
self.sock.bind(('0.0.0.0', port))
self.sock.listen(1)
def handler(self, c, a):
while True:
try:
data = c.recv(1024) #loop won't run until recieved dat
except:
c.shutdown(socket.SHUT_RDWR)
c.close()
break
print("Chat:    ", str(data, 'utf-8'))
if not data:
c.close()
break
def run(self):
self._stop = False
while not self._stop: 
c, a = self.sock.accept()  ##c is client and a is address
cThread = threading.Thread(target=self.handler, args=(c,a))
cThread.daemon = True
cThread.start()
self.connections.append(c)
print("Server:    ", str(a[0]) + ':' + str(a[1]), "connected")
self.close()
def shutdownServer(self):
self._stop = True 
def close(self):
print('Closing server')
if self.sock:
self.sock.close()
self.sock = None
def serverRun(port, stop):
while True:
print("server port: " + str(port))
actual_server = Server(port)
actual_server.run()
if(stop):
print("Stopping server thread")
break

以下是设置线程并运行服务器的代码:

def main():
stopThreads = False
thread = threading.Thread(target = server.serverRun, args=(1, lambda : stopThreads,))
thread.start()
time.sleep(1)
stopThreads = True
thread.join()
print("server thread killed")
main()

如有任何帮助,我们将不胜感激。

编辑:编辑是为了澄清问题,所以关闭线程更重要的是将变量传递给在线程中运行的类,这样它就可以在线程试图停止时关闭套接字。

好吧,所以我发现阻塞程序是socket.accept((函数。因此,对于任何可能有终止服务器线程相同问题的人,您只需在sock.accept((之前使用sock.select((来检查是否有任何传入连接。如果使用sock.select((并添加超时,则整个循环将在指定的等待连接的时间后运行,因此,如果事件已通知线程这样做,则线程可能会被终止,如果没有,则线程将再次查找连接。

您可以使用线程事件函数(stovfl在主线程的注释中提到了这个函数(来告诉线程何时停止。

以下是我如何更改代码,使其现在可以自我终止:

def run(self, running):
while running.is_set(): 
timeout = 2
readable, writable, errored = select.select([self.sock], [], [], timeout)
for s in readable:
if s is self.sock:
client_socket, a = self.sock.accept()  ##c is client and a is address
cThread = threading.Thread(target=self.handler, args=(client_socket, a))
cThread.daemon = True
cThread.start()
self.connections.append(client_socket)
print("Server:    ", str(a[0]) + ':' + str(a[1]), "connected")
self.close()
def serverRun(running, port):
while running.is_set():
print("server port: " + str(port))
actual_server = Server(port)
actual_server.run(running)

主菜单更改为:

def main(): 
running = threading.Event()
running.set()
thread = threading.Thread(target=server.serverRun, args=(running, 1))
thread.start()
time.sleep(30)
print("Event running.clear()")
running.clear()
print('Wait until Thread is terminating')
thread.join()
print("EXIT __main__")
main()

最新更新