python函数没有作为线程运行

时间:2017-12-03 16:08:21

标签: python multithreading

这是在python 2.7.12

中完成的

serialHelper是一个类模块arround python serial,这段代码确实很好用

#!/usr/bin/env python
import threading
from time import sleep
import serialHelper

sh = serialHelper.SerialHelper()

def serialGetter():
    h = 0
    while True:
        h = h + 1
        s_resp = sh.getResponse()
        print ('response ' + s_resp)
        sleep(3)

if __name__ == '__main__':
    try:
        t = threading.Thread(target=sh.serialReader)
        t.setDaemon(True)
        t.start()
        serialGetter()
        #tSR = threading.Thread(target=serialGetter)
        #tSR.setDaemon(True)
        #tSR.start()
    except Exception as e:
        print (e)

然而,尝试将serialGetter作为线程运行,并表示它已经死了。 该函数无法作为线程运行的任何原因?

1 个答案:

答案 0 :(得分:2)

引自the Python documentation

  

当没有剩下活着的非守护程序线程时,整个Python程序退出。

因此,如果您setDaemon(True)每个新线程然后退出主线程(通过从脚本末尾掉下来),整个程序将立即退出。这会杀死所有线程。要么不使用{{1}},要么不首先在您想要等待的所有主题上调用join(),否则不要退出主线程。

稍微退一步,考虑一个守护程序线程的预期用例可能会有所帮助。在Unix中,守护程序是一个在后台运行并且(通常)通过网络或本地进程代表远程客户端提供请求或执行操作的进程。同样的基本思想适用于守护程序线程:

  1. 使用某种工作队列启动守护程序线程。
  2. 如果你需要在线程上完成一些工作,你可以将它交给工作对象。
  3. 当您想要该工作的结果时,您可以使用事件或未来等待它完成。
  4. 在请求完成某项工作后,您最终总是等待它完成,或者可能取消它(如果您的工作协议支持取消)。
  5. 您不必在程序终止时清理守护程序线程。当没有其他线程离开时,它就会悄然消失。
  6. 问题在于步骤(4)。如果您忘记某些工作对象,并在不等待其完成的情况下退出应用程序,则工作可能会中断。守护程序线程don't gracefully shut down,因此您可以使外部世界处于不一致状态(例如,不完整的数据库事务,从未关闭的文件等)。使用常规线程通常更好,并用明确的&#34替换步骤(5);完成工作并关闭"主要线程在退出之前将其交给工作线程的工作对象。然后,工作线程识别此对象,停止等待工作队列,并在其不再执行任何其他操作后终止自身。这是稍微前期工作,但如果工作对象无意中被遗弃,则会更加安全。

    由于以上所有原因,我建议不要使用守护程序线程,除非你有充分的理由。