4

我什么时候用dummy_threading

我曾认为它可能会用模拟线程替换系统级线程,以防 Python 无法使用系统级线程。

但是当我运行这个时:

import dummy_threading as threading

semaphore = threading.Semaphore()
def f(i):
    semaphore.acquire()
    print i
for i in xrange(10):
    threading.Thread(target=f, args=(i,)).start()
for _ in xrange(10):
    semaphore.release()

我得到0了,程序没有终止。不仅如此,Python 还莫名其妙地继续吞噬我电脑的内存,直到它一无所有。

当我运行这个:

import threading

semaphore = threading.Semaphore()
def f(i):
    semaphore.acquire()
    print i
for i in xrange(10):
    threading.Thread(target=f, args=(i,)).start()
for _ in xrange(10):
    semaphore.release()

我得到0 1 3 5 7 9 2 4 6 8了预期。

我一定是误会了dummy_threading。我什么时候使用它?

仅供参考,我在 Windows 7 和 Fedora 18 上进行了比较,得到了相同的结果。

编辑:但是,以下给出0 1 2 3 4 5 6 7 8 9

import dummy_threading as threading

event = threading.Event()
def f(i):
    event.wait()
    print i
for i in xrange(10):
    threading.Thread(target=f, args=(i,)).start()
event.set()

最大的问题是:做dummy_threading 什么,或者什么时候会给出与 相同的行为threading

4

2 回答 2

5

该模块旨在在您的平台上可用且不可用时thread使用threading

您传递给它的函数被同步调用,并且您.start()立即调用。第一个函数获取信号量,打印,然后调用第二个函数并阻塞。它同步运行并且永不返回。

dummy_thread文档中:

注意不要使用这个模块,因为正在创建的线程可能会发生死锁,阻塞等待另一个线程被创建。这通常发生在阻塞 I/O 上。

并来自EFF-bot 帖子(否则很短并且缺少工作链接):

帮助程序使编写使用支持的线程的代码变得更容易,但仍然在没有线程支持的 Python 版本上运行。虚拟模块只是按顺序运行线程。

注意使它更容易的部分;如果没有实际的线程,您不能期望代码运行dummy_threading时不会像您的示例中那样死锁。

于 2013-04-21T17:38:15.843 回答
4

dummy_threading中,线程只是函数包装器,它们是按顺序执行的。

第二个片段的问题是dummy_threading.Thread.start()直到相应的f调用退出才返回。线程0将获取信号量,然后线程1将尝试获取它并阻塞。没有任何东西会释放信号量,因为只有一个线程被阻塞。

更新:对虚拟事件行为进行了一些研究。

事实上,所有的Semaphore,Event等都Conditiondummy_threading正常情况完全相同,threading只是它们使用了虚拟锁(为此做了一些导入魔法。)因此,当您调用 时event.wait(),底层锁永远不会阻塞线。两者都不会阻塞 使用的锁Semaphore,而是在内部信号量循环,直到资源可用:

 while self.__value == 0:  # Here it will loop forever
    if not blocking:
        break
    ....
    self.__cond.wait()

我认为,虚拟事件违反了这样的假设,即无论何时在wait没有参数的情况下调用返回,这意味着该事件已设置,但不确定是否可以轻松帮助。

于 2013-04-21T17:52:23.380 回答