2

我遇到了一个棘手的问题来测试守护线程是否正在运行。我创建的守护线程应该在后台运行以保持服务运行,因此我执行以下操作来创建它并使其保持活动状态:

创建:

ASThread = threading.Thread(target = initAirserv, args=[],)
ASThread.setDaemon(True)
ASThread.start()

方法内部initAirserv()

def initAirserv(self, channel="15"):
        interface = self.execAirmon(options="start", interface=self.interface)
        port = self.plug_port
        if interface != "removed":
            if channel=="15":
                command = "airserv-ng -d " +str(interface)+" -p "+str(port)
            else:
                command = "airserv-ng -d " +str(interface)+" -p "+str(port)+" -c"+str(channel)
        else:
            return None
        AServConn=self.init_Plug()
        if AServConn:
            (stdin, stdout, stderr) = AServConn.exec_command(command)
            serv_op = stdout
            serv_er = stderr
            ##### keep the daemon thread run persistently ####
            a = 0 
            while 1:
                a += 1
        else:
            logging.debug( "SSH Error" )

最后几行的目的是用一种愚蠢的方式让线程保持忙碌。然而,在启动了这个守护线程之后,我做了别的事情,当我回来检查线程时,如下所示:

if ASThread.is_alive() == 1:
    # do something

if 主体永远不会被执行。有人可以向我解释为什么会这样吗?运行一个执行需要一直忙的事情的线程的最佳方法是什么?非常感谢。

4

2 回答 2

2

发布的代码没有加起来。initAirserv正如所发布的是类上的方法,但initAirserv传递给Thread构造函数的方法不是。

execAirmon如果不知道什么和做什么,以及您的应用程序中还会发生什么,也很难说出具体init_Plug的内容。

一般来说,我会说你是对的。这应该有效。事实上,这并不意味着你的假设是错误的。

  • 您确定execAirmon返回不等于“已删除”的内容吗?
  • 你确定init_Plug返回一个非假对象吗?
  • 你确定没有抛出异常吗?(我假设您会注意到一个虚假的堆栈跟踪,那么您的应用程序的其他部分是否可能会在不被注意的情况下吞噬它们?)
于 2012-03-21T21:27:06.800 回答
0

我的一些信息是几个月前的,事情可能已经改变,所以请多多包涵。

如果您使用基于标准 C 的 Python 并且正在编写多线程应用程序,则需要了解全局解释器锁 (GIL) 限制。也就是说一次只能运行一个线程。如果您愿意使用 Python C 接口包之一并用 C 编写大量代码,则函数调用的 C 部分可以线程化,不受 GIL 限制。

Python 具有出色的多进程支持和库,并且因为您正在同步进程,所以 GIL 限制不适用。

有关于修复 GIL 限制的讨论,但现在这是一个你必须接受的问题。

恕我直言,我选择 Python 来用 Python 而不是 C 来编写软件,除非必须解决一个非常具体的问题。Python 在很多事情上都是一门优秀的语言,但 GIL 的限制鼓励我学习一种支持更好的事件同步的语言,也就是多线程环境。

我希望这有帮助。

于 2012-03-21T17:56:49.083 回答