我如何在python中进行线程化?

时间:2010-07-15 18:20:17

标签: python multithreading

使用此网站的代码: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

5 个答案:

答案 0 :(得分:6)

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

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

使用threading.Lock围绕print语句进行同步,以便多个print不能同时发生。

答案 1 :(得分:5)

打印由多个操作码实现,特别是换行符是单独的操作码。 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        

答案 2 :(得分:2)

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

答案 3 :(得分:0)

因为打印不是atomic,所以线程的打印可以随时被另一个线程中断。如果thread1完成了一半打印并且thread2中断并开始打印,则输出将与thread1和thread2的输出交错。

答案 4 :(得分:0)

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