【问题标题】:How to kill a Server thread in Python如何在 Python 中杀死服务器线程
【发布时间】:2020-08-12 03:28:06
【问题描述】:

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

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

这是我的服务器代码:

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()

任何帮助将不胜感激。

编辑:编辑澄清问题不是关闭线程,而是将变量传递给正在线程中运行的类,因此它可以在线程试图停止时关闭其套接字。

【问题讨论】:

  • 关注这个答案close a thread on multithreading一个社区
  • @stovfl 这个不行,因为服务器的接收线程,它一直在thread.join()处等待
  • 没错,我已将 while running.is_set 添加到所有 while 循环中。好像还是不行
  • 它指出,你在问 B 但需要 A。这个:data = c.recv(... 正在阻塞。关闭连接或发送 TERMINATION 消息并中断while ...
  • @stovfl 抱歉,是的,我需要知道如何告诉线程停止,当我这样做时,关闭连接以便线程可以加入。不幸的是,我找不到一种方法来告诉连接关闭而不向它发送消息,因为它会阻止其他任何东西在 while 循环中运行

标签: python multithreading server


【解决方案1】:

好的,所以我发现阻止程序是 socket.accept() 函数。因此,对于可能在终止服务器线程方面遇到相同问题的任何人,您可以在 sock.accept() 之前使用 sock.select() 来检查是否有任何传入连接。如果您使用 sock.select() 并为其添加超时,则整个循环将在等待连接的分配时间后运行,因此如果事件告诉它这样做并且没有,则线程可以被杀死t,它将再次寻找连接。

您可以使用线程事件函数(在主线程的 cmets 中提到的 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)

并且 main 改为:

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()

【讨论】:

    猜你喜欢
    • 2019-10-12
    • 2017-01-22
    • 2021-03-12
    • 1970-01-01
    • 2011-04-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多