Python 多线程初学遇到的输出混叠问题

照着书上敲了一个多线程的例子:

#!/usr/bin/env python

import thread
from time import sleep, ctime

loops = [4, 2]

def loop(nloop, nsec, lock):
    print 'start loop', nloop, 'at:', ctime()
    sleep(nsec)
    print 'loop', nloop, 'done at:', ctime()
    lock.release()

def main():
    print 'starting at:', ctime()
    locks = []
    nloops = range(len(loops))

    for i in nloops:
        lock = thread.allocate_lock()
        lock.acquire()
        locks.append(lock)

    for i in nloops:
        thread.start_new_thread(loop,
                    (i, loops[i], locks[i]))

    for i in nloops:
        while locks[i].locked():
            pass

    print 'all done at:', ctime()

if __name__ == '__main__':
    main()

这里解释一下 21 行,accquire 方法的调用表示把“把锁锁上”,下面的 start 循环就是把准备好的线程一个个启动了,再下面那个的那个 pass 循环,是在“等待所有的锁解开”,这里需要注意的是,他是从第一个锁开始“等待”的,也就是说,就算后面的锁都解了,但是第一个还锁着,他也不知道,也不管的,简单想一下就明白这样处理是没问题的,因为总要等到所有的锁都解开才能跑后续的代码嘛

但是问题出现了,在输出的时候,得到这样的输出

starting at: Fri Aug 03 21:38:55 2012
start loopstart loop  01  at:at:  Fri Aug 03 21:38:55 2012Fri Aug 03 21:38:55 2012

loop 1 done at: Fri Aug 03 21:38:57 2012
loop 0 done at: Fri Aug 03 21:39:03 2012
all done at: Fri Aug 03 21:39:03 2012

正如所见,两个线程开始的那个打印语句冲突了,在同一行输出,这应该是一个多线程对输出设备写操作上的问题,怎么解决呢,自己刚学多线程,完全没有思路,于是上 stackoverflow 去问,看到别人这个问题的答案 http://stackoverflow.com/quest… ,

The easiest way might be to just override sys.stdout.
Slightly modifying an example from the multiprocessing
manual:

from multiprocessing import Process
import os
import sys

def info(title):
    print title
    print 'module name:', __name__
    print 'parent process:', os.getppid()
    print 'process id:', os.getpid()

def f(name):
    sys.stdout = open(str(os.getpid()) + ".out", "w")
    info('function f')
    print 'hello', name

if __name__ == '__main__':
    p = Process(target=f, args=('bob',))
    p.start()
    q = Process(target=f, args=('fred',))
    q.start()
    p.join()
    q.join()
And running it:

$ ls
m.py
$ python m.py
$ ls
27493.out  27494.out  m.py
$ cat 27493.out
function f
module name: __main__
parent process: 27492
process id: 27493
hello bob
$ cat 27494.out
function f
module name: __main__
parent process: 27492
process id: 27494
hello fred

看起来,他是重载了输出文件,这个比较高深,暂时看不懂,而且暂时也没有深入的涉及到 python 多线程的应用,所以这个问题暂时放着吧,等以后需要的时候回头来看

2 thoughts on “Python 多线程初学遇到的输出混叠问题

  1. 解决python多线程输出重叠问题,可以从输出入手,一般输出采用的是print函数,Print函数是可以被线程打断,如果不被打断的话就不会出现重叠的情况。可以采用sys.stdout.write来解决。

    • 嗯,这个问题后来就放下没管了,下次要用的时候可以试试这个,学习了,thanks!

Leave a Reply to ZRJ Cancel reply

Your email address will not be published. Required fields are marked *