键盘中断线程

2 投票
2 回答
1961 浏览
提问于 2025-04-18 10:34

我正在用pyBonjour支持写一个简单的TCP套接字服务器。为此,我想到了使用线程。问题是我不知道怎么让服务器停止……我觉得下面的方法应该可以用(根据这个),但实际上并没有效果。

有没有更好的方法可以做到这一点(能正常工作的)……

import SocketServer
import threading
import pybonjour
import select
import time

class BonjourThread(threading.Thread):        
    def run(self):
        sdRef = pybonjour.DNSServiceRegister(name = 'MacroServer - Mac',
                                     regtype = '_macroserver._tcp',
                                     port = 12000,
                                     callBack = self.bonjour_register_callback)

        while True:
            ready = select.select([sdRef], [], [])
            if sdRef in ready[0]:
                pybonjour.DNSServiceProcessResult(sdRef)

    def bonjour_register_callback(self, sdRef, flags, errorCode, name, regtype, domain):
        if errorCode == pybonjour.kDNSServiceErr_NoError:
            print 'Bonjour started'


class TCPThread(threading.Thread):
    def run(self):
        try:
            HOST, PORT = "localhost", 12000
            server = SocketServer.TCPServer((HOST, PORT), MyTCPHandler)
            print 'TCP server started'
            server.serve_forever()
        except KeyboardInterrupt:
            print 'Closing Down'
            exit()

class MyTCPHandler(SocketServer.BaseRequestHandler):
    def handle(self):
        try:
            # self.request is the TCP socket connected to the client
            self.data = self.request.recv(1024).strip()
            print "{} wrote:".format(self.client_address[0])
            print self.data
            # just send back the same data, but upper-cased
            self.request.sendall(self.data.upper())
        except KeyboardInterrupt:
            print 'Closing Down'
            exit()

if __name__ == "__main__":
    try:
        thread1 = TCPThread()
        thread1.start()
        thread2 = BonjourThread()
        thread2.start()
        while True: time.sleep(100)
    except (KeyboardInterrupt, SystemExit):
        print 'Received keyboard interrupt, quitting threads.\n'
    finally:
        print 'And its bye from me'

2 个回答

2

来自你链接的地方:

将 thread.daemon 设置为 True 会导致线程在主程序结束时自动终止。

你在代码中没有设置这个,所以线程才没有停止。

至于更好的方法,你可以创建自己的信号处理器来终止线程,但我不确定这样做是否比以下方法更好:

thread.daemon=True
2

在Python中,只有主线程会收到键盘中断信号。你想要如何处理你的socket服务器和各种客户端的终止问题可能会变得比较复杂。我曾经做过日志服务器,我把所有的socket放在一个主列表里,并用锁来保护这个列表,然后在收到键盘中断时关闭所有的socket,最后等待程序结束。你也可以把线程标记为守护线程,这样程序就可以直接退出,让操作系统来处理socket的清理工作。

撰写回答