2017-02-17 38 views
1

我有一些代码在一个线程中运行使用套接字来等待进入的客户端连接:终止循环中使用流选择3

import threading 
import socket 
import selectors 

class Server(threading.Thread): 
    def __init__(self): 
     # instantiate socket 
     self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 

     # bind the socket 
     self.socket.bind(("localhost", 50000)) 

    def run(self): 
     # create selector to interface with OS 
     sel = selectors.DefaultSelector() 

     # register the connection handler for when a client connects 
     sel.register(self.socket, selectors.EVENT_READ, self.handle_connection) 

     while True: 
      events = sel.select() 
      for key, _ in events: 
       # run the callback 
       key.data() 

    def handle_connection(self): 
     # handle a request on the socket 
     data = self._socket.accept() 

     # do stuff with data... 

    def stop(self): 
     # what to do? 
     pass 

这个代码进入while True循环,并呼吁sel.select()哪些块直到从self._socket读取内容为止,此时它会调用回调self.handle_connection(与我的问题无关)。这很好,但我也希望能够使用线程的stop方法打破while True循环,这样我的主程序循环可以停止线程并正常关闭服务器。

我不能只检查像while self.running:这样的标志,因为sel.select()会阻塞,直到读取到某个东西。我也想过使用选择器的错误处理机制,但我不一定要在错误/异常期间关闭服务器。

看来我需要选择器从第二个流中读取,其中包含一个特殊命令来停止循环,但这看起来过于复杂。任何建议,将不胜感激!

+0

'select'中的'timeout'参数可能会有帮助吗? https://docs.python.org/3.4/library/selectors.html#selectors.BaseSelector.select – Highstaker

+0

啊,是的,就是这样!我添加了1秒的超时时间,并将'while True'循环更改为'while self.server_running',并将'stop'方法设置为'self.server_running = False'。就如此容易!谢谢。 – Sean

+0

没问题!我会发布一个答案,以便其他人可以使用它,如这里所建议的https://meta.stackexchange.com/questions/291167/posting-an-answer-after-posting-it-in-comment-that-solved-在-OPS-问题/ 291168#291168 – Highstaker

回答

2

既然你说你行与使用while self.flag而不是while True,你可以指定一个timeout参数,as explained in the docs。只需确保在输入for key, _ in events:循环之前检查您的数据