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