栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

如何退出多线程程序?

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

如何退出多线程程序?

我在您的代码中看到了一些行为异常的原因。

  1. Ctrl + C在主线程中导致“ KeyboardInterrupt”异常。因此,您应该在那里处理。
  2. 您的套接字处于阻止模式。这将导致多个套接字函数阻塞调用线程,直到该函数返回为止。在此状态下,线程无法对任何终止事件作出反应。
  3. 正如您已经说过的:线程的run()函数中的无穷循环是…确实无穷无尽。因此线程执行永无休止(至少并非没有意外的异常)。您应该使用某种同步对象,例如threading.Event对象,以便能够从外部告知线程它应该终止。
  4. 我不鼓励在主线程中使用raw_input()。想象一下,当您有多个喊线程时会发生什么。
  5. 为什么在Shout类中发送了消息后,为什么总是关闭并重新连接套接字?由于设置成本,仅在特殊情况下才应重新建立网络连接。
  6. 如果没有用于通信的帧协议,那么当recv()函数返回时,您将永远无法期望接收到另一主机发送的所有数据。
  7. 线程对象的start()函数不返回值或对象。因此,保存返回值(= None)没有多大意义。
  8. 您永远都不能期望send()函数传输所有传递的数据。因此,您必须检查函数的结果并适当地处理并非所有字节都已真正传输的情况。
  9. 要学习线程,肯定比网络通信要解决更好的问题,因为该主题本身确实很复杂。

除了所有这些以外,这是我尝试解决的方法。仍有很多可以改进的地方。您也应该考虑Mark
Tolonen的答案,因为肯定提供了SocketServer类可以简化处理此类事件的几件事。但是您也应该继续学习基础知识。

#!/usr/bin/env pythonimport threadingimport socketimport timeimport errnoclass StoppableThread(threading.Thread):    def __init__(self):        threading.Thread.__init__(self)        self.stop_event = threading.Event()    def stop(self):        if self.isAlive() == True: # set event to signal thread to terminate self.stop_event.set() # block calling thread until thread really has terminated self.join()class Accept(StoppableThread):    def __init__(self, port):        StoppableThread.__init__(self)        self.port = port        self.threads = []    def run(self):  # handle connection acception        conn = socket.socket(socket.AF_INET, socket.SOCK_STREAM)        conn.bind(('', self.port ))        conn.listen(5)        # set socket timeout to ~10ms        conn.settimeout(0.01)        while self.stop_event.is_set() == False: try:     csock, caddr = conn.accept()     # spawn a new thread to handle the client connection     listen_thread = Listen(csock, caddr)     self.threads.append(listen_thread)     listen_thread.start() except socket.timeout:     # socket operation timeout     # clear all terminated threads from thread list          for thread in self.threads:         if thread.isAlive() == False:  self.threads.remove(thread)        self.stop_threads()    def stop_threads(self):        # stop all running threads        for listen_thread in self.threads: if listen_thread.isAlive() == True:     listen_thread.stop()        self.threads = []class Listen(StoppableThread):    def __init__(self, csock, caddr):        StoppableThread.__init__(self)        self.csock = csock        self.caddr = caddr        self.csock.setblocking(False)    def run(self):  while self.stop_event.is_set() == False:  try:          recv_data = self.csock.recv(250)     if len(recv_data) > 0:     print str(self.caddr)+": " + recv_data         self.csock.send("got it")   else:         # connection was closed by foreign host         self.stop_event.set() except socket.error as (sock_errno, sock_errstr):     if (sock_errno == errno.EWOULDBLOCK):         # socket would block - sleep sometime         time.sleep(0.1)   else:         # unexpected / unhandled error - terminate thread         self.stop_event.set()        channel.close()class Shout(StoppableThread):    def __init__(self, sport):        StoppableThread.__init__(self)        self.sport = sport    def run(self):        while self.stop_event.is_set() == False: try:         address = raw_input("who u talking to? ")     conn = socket.socket(socket.AF_INET, socket.SOCK_STREAM)     conn.connect((address, self.sport))     break except socket.error:     # handle connection problems     print "can't connect to "+ str(address) except:      # exit thread in case of an unexpected error     self.stop_event.set()        while self.stop_event.is_set() == False: try:      # chat loop: send messages to remote host      print "what to send? :",     msg = raw_input()     # beware: send() function may block indefinitly here and it might not send all bytes as expected !!     conn.send(msg) except:     # exit thread in case of an unexpected error     self.stop_event.set()        # close socket before thread terminates        conn.close()def main():    do_exit = False    server_port = 2727    # start server socket thread    accept = Accept(server_port)    accept.start()    # start transmitting client socket thread    shout = Shout(server_port)    shout.start()    while do_exit == False:        try: # sleep some time time.sleep(0.1)        except KeyboardInterrupt: # Ctrl+C was hit - exit program do_exit = True    # stop all running threads    shout.stop()    accept.stop()    # exit main program after all threads were terminated gracefullyif __name__ == "__main__":    main()


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/596441.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号