【问题标题】:How do I do threading in python?如何在 python 中进行线程化?
【发布时间】:2010-07-15 18:20:17
【问题描述】:

使用本网站的代码:http://www.saltycrane.com/blog/2008/09/simplistic-python-thread-example/

代码是

import time
from threading import Thread

def myfunc(i):
    print "sleeping 5 sec from thread %d" % i
    time.sleep(5)
    print "finished sleeping from thread %d" % i

for i in range(10):
    t = Thread(target=myfunc, args=(i,))
    t.start()

我得到这个输出:

sleeping 5 sec from thread 0
sleeping 5 sec from thread 1
sleeping 5 sec from thread 2
sleeping 5 sec from thread 3
sleeping 5 sec from thread 4
sleeping 5 sec from thread 5
sleeping 5 sec from thread 6
sleeping 5 sec from thread 7
sleeping 5 sec from thread 8
sleeping 5 sec from thread 9
finished sleeping from thread 0
finished sleeping from thread 2
finished sleeping from thread 4
finished sleeping from thread 1finished sleeping from thread 6finished sleeping from   thread 8
finished sleeping from thread 5finished sleeping from thread 7finished sleeping from thread 9

finished sleeping from thread 3

这里发生了什么?我可以接受没有按顺序打印的线程,因为这是可能的,但为什么它们最后没有在换行符上打印?我在windows xp下使用python 2.6

【问题讨论】:

    标签: python multithreading


    【解决方案1】:

    您刚刚发现为什么使用线程编程很困难 :)

    发生的情况是,您的所有线程几乎同时被唤醒。一个线程开始打印“从线程 1 完成睡眠”,在它有机会打印最后一个“\n”之前,另一个线程出现并打印“从线程 6 完成睡眠”,然后继续。这些换行符并没有被跳过,它们只是被移动并聚集在其他地方。这可能就是为什么在“finished...3”之前跳过了一行的原因。我的猜测是由于格式化而删除了许多尾随空白行。

    使用threading.Lock 围绕您的print 语句进行同步,这样多个prints 就不会同时发生。

    【讨论】:

      【解决方案2】:

      print 由多个操作码实现,特别是换行符是一个单独的。 Python 将在操作码之间进行上下文切换:

      >>> def f(o):
      ...     print o
      ...     
      ...     
      
      >>> from dis import dis
      
      >>> dis(f)
        2           0 LOAD_FAST                0 (o)
                    3 PRINT_ITEM          
                    4 PRINT_NEWLINE       
                    5 LOAD_CONST               0 (None)
                    8 RETURN_VALUE        
      

      【讨论】:

        【解决方案3】:

        我认为当一个线程没有打印新行时,这是因为在第一个线程打印新行之前控件已传递给另一个线程。

        【讨论】:

        • 我认为你可能是对的。这一定意味着打印命令一次只发送一个字符。有 10 个换行符,因为我检查过......奇怪的是只有换行符被移动。一定只是时机。
        • 它不是一次打印一个字符(当然,在某种程度上它是);只是 print 语句的行为由两个步骤组成:“打印参数”,然后是“如果参数后面没有逗号,则打印换行符”。 Python 线程调度程序可以在这两个步骤之间切换线程,但它不会在其中一个步骤中切换 - 因此您会看到这种行为。
        【解决方案4】:

        因为 print 不是atomic 一个线程的打印可以随时被另一个线程中断。如果线程 1 打印一半,线程 2 中断它并开始打印,则输出将与线程 1 和线程 2 的输出交错。

        【讨论】:

          【解决方案5】:

          确实,打印不是线程安全的。在您的示例中,您可能想要使用日志记录模块。或者你可以创建一个thread safe print

          【讨论】:

            猜你喜欢
            • 2011-10-23
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2015-08-29
            • 2011-10-17
            • 2014-01-26
            • 1970-01-01
            • 2023-03-20
            相关资源
            最近更新 更多