簡體   English   中英

如何殺死 Python 中的服務器線程

[英]How to kill a Server thread in 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()

任何幫助,將不勝感激。

編輯:為澄清問題而進行的編輯不是關閉線程,而是將變量傳遞給正在線程中運行的 class ,因此它可以在線程試圖停止時關閉其套接字。

好的,所以我發現阻止程序是 socket.accept() function。 因此,對於可能在終止服務器線程方面遇到相同問題的任何人,您可以在 sock.accept() 之前使用 sock.select() 來檢查是否有任何傳入連接。 如果您使用 sock.select() 並為其添加超時,則整個循環將在等待連接的分配時間后運行,因此如果事件告訴它這樣做並且它沒有',則可以殺死線程t,它將再次尋找連接。

您可以使用線程事件 function(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()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM