如何在python中安全地退出多线程套接字服务器?

时间:2015-07-21 16:35:53

标签: python multithreading sockets

我刚刚写了一个非常简单的udp聊天程序以获得乐趣。它按预期工作,但现在我不知道如何安全地退出它。由于此处存在问题,似乎无法接受调用sys.exit():Why does sys.exit() not exit when called inside a thread in Python?

只需通过ctrl + c提升信号就会失败,因为它会被raw_input()拦截。

有没有合适的方式处理它?<​​/ p>

这是我的代码段:

import socket
import threading

s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)  
address = ('192.168.1.xxx', 31500)  
target_address = ('192.168.1.xxx', 31500)
s.bind(address)  

print('waiting for input...')

def rcv():
    while True:
        data, addr = s.recvfrom(2048)  
        if not data:            
            continue
        print 'Received: #### ', data
        print '\n'

def send():
    while True:
        msg = raw_input()
        if not msg:
            continue
        s.sendto(msg, target_address)

t1 = threading.Thread(target = rcv)
t2 = threading.Thread(target = send)

t1.start()
t2.start()

1 个答案:

答案 0 :(得分:0)

取代我之前的回答: 我将您的代码修改为:

import socket
import threading

s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)  
address = ('192.168.1.xxx', 31500)  
target_address = ('192.168.1.xxx', 31500)
s.bind(address)  

EXIT_MSG_GUARD = "@Quit!"
print('waiting for input...')

def rcv():
    while True:
        data, addr = s.recvfrom(2048)  
        if not data:            
            continue
        print 'Received: #### ', data
        print '\n'

def send():
    while True:
        msg = raw_input()
        if not msg:
            continue
        else:
            s.sendto(msg, target_address)
            if msg == EXIT_MSG_GUARD:
                return

t1 = threading.Thread(target = rcv)
t2 = threading.Thread(target = send)

t1.setDaemon(True)

t1.start()
t2.start()

我做了两件事:

  • 添加一个消息保护(在我的示例@Quit!中,但您可以将其更改为您喜欢的任何内容):当用户输入该文本后,t2线程结束后。
  • 创建线程t1 daemonic,这意味着当主线程和所有非守护程序线程结束时,这也将结束,程序将退出。
  

注意:守护程序线程在关闭时突然停止。他们的资源(例如打开文件,数据库事务等)可能无法正确发布。如果您希望线程正常停止,请使它们成为非守护进程并使用合适的信号机制,例如事件。

作为守护程序线程的替代方法,您可以使用已发布的解决方案here(同时注意限制!)。它更好(和推荐),但需要更多的工作,包括对rcv功能的一点改动