python多线程实现

本人初学者开始第一篇博客,记录学习的点点滴滴,以作为备忘录,也希望能同大家一起分享。有理解错误的地方希望大家指正。 python中的多线程我参考了(http://www.cnblogs.com/fnng/p…)中的介绍,介绍的很入门很详细。介绍了threading的基本用法。

最简单的情况是:

import threading
import time
def fuction(i):
    print("我是第%s个进程,开始时间是%s"%(i+1,time.ctime()))
    time.sleep(2)               #子程序等2秒。。
    print("我是第%s个进程,结束时间是%s"%(i+1,time.ctime()))
threads=[threading.Thread(target=fuction,args=(i,) ) for i in range(5)]
for t in threads:
    t.start()
print("程序结束,%s:"%(time.ctime()))

#输出为-------------------
我是第1个进程,开始时间是Sun Oct 22 17:45:37 2017
我是第2个进程,开始时间是Sun Oct 22 17:45:37 2017
我是第3个进程,开始时间是Sun Oct 22 17:45:37 2017
我是第4个进程,开始时间是Sun Oct 22 17:45:37 2017
我是第5个进程,开始时间是Sun Oct 22 17:45:37 2017
**程序结束,Sun Oct 22 17:45:37 2017:**          #主线程继续执行,不等待,也不杀死子线程
我是第1个进程,结束时间是Sun Oct 22 17:45:39 2017
我是第2个进程,结束时间是Sun Oct 22 17:45:39 2017
我是第5个进程,结束时间是Sun Oct 22 17:45:39 2017
我是第3个进程,结束时间是Sun Oct 22 17:45:39 2017
我是第4个进程,结束时间是Sun Oct 22 17:45:39 2017

这里介绍另外两个函数:setDaemon()、join()
join:如在一个线程B中调用threada.join(),则threada结束后,线程B才会接着threada.join()往后运行。
setDaemon:主线程A启动了子线程B,调用b.setDaemaon(True),则主线程结束时,会把子线程B也杀死,与C/C++中得默认效果是一样的。

比如我想让主程序等待子程序完成之后再运行,可以是用t.join()
其中t是指某个子进程,如t1,t2….然后join()可以有一个参数,主进程等待多少秒,如t1.join(2)指在t1子进程开始后,主进程等待2秒就继续执行。

def fuction(i):
    print("我是第%s个进程,开始时间是%s"%(i+1,time.ctime()))
    time.sleep(i*2)               #模拟子进程的运行时间,ID越大时间越长
    print("我是第%s个进程,结束时间是%s"%(i+1,time.ctime()))
threads=[threading.Thread(target=fuction,args=(i,) ) for i in range(5)]
for t in threads:
    t.start()
threads[1].join(1)              #主进程在第二个子进程开始后阻塞1秒再运行
print("主进程:,%s:"%(time.ctime()))

#输出---------------------
我是第1个进程,开始时间是Sun Oct 22 18:12:14 2017
我是第1个进程,结束时间是Sun Oct 22 18:12:14 2017
我是第2个进程,开始时间是Sun Oct 22 18:12:14 2017     #第二个子进程14秒开始
我是第3个进程,开始时间是Sun Oct 22 18:12:14 2017
我是第4个进程,开始时间是Sun Oct 22 18:12:14 2017
我是第5个进程,开始时间是Sun Oct 22 18:12:14 2017
主进程:Sun Oct 22 18:12:15 2017:                  #主进程在阻塞一秒后的15秒开始启动运行
我是第2个进程,结束时间是Sun Oct 22 18:12:16 2017
我是第3个进程,结束时间是Sun Oct 22 18:12:18 2017
我是第4个进程,结束时间是Sun Oct 22 18:12:20 2017
我是第5个进程,结束时间是Sun Oct 22 18:12:22 2017

若想等所有的子进程都完成后,主进程在进行可以,简单情况可以用最慢的一个子进程来对主进程进行阻塞,这里最慢的是第5个子进程。可以:threads[4].join()。

import tensorflow as tf
import numpy as np
import random
import threading
import time


def fuction(i):
    print("我是第%s个进程,开始时间是%s"%(i+1,time.ctime()))
    time.sleep((i+0.5)*2)               #模拟子程序运行随机秒
    print("我是第%s个进程,结束时间是%s"%(i+1,time.ctime()))
threads=[threading.Thread(target=fuction,args=(i,) ) for i in range(5)]
for t in threads:
    t.start()
threads[4].join()
print("主进程:%s:"%(time.ctime()))

#输出-----------------------
我是第1个进程,开始时间是Sun Oct 22 18:29:28 2017
我是第2个进程,开始时间是Sun Oct 22 18:29:28 2017
我是第3个进程,开始时间是Sun Oct 22 18:29:28 2017
我是第4个进程,开始时间是Sun Oct 22 18:29:28 2017
我是第5个进程,开始时间是Sun Oct 22 18:29:28 2017
我是第1个进程,结束时间是Sun Oct 22 18:29:29 2017
我是第2个进程,结束时间是Sun Oct 22 18:29:31 2017
我是第3个进程,结束时间是Sun Oct 22 18:29:33 2017
我是第4个进程,结束时间是Sun Oct 22 18:29:35 2017
我是第5个进程,结束时间是Sun Oct 22 18:29:37 2017
主进程:Sun Oct 22 18:29:37 2017:                      #主进程等到最后一个子进程结束后才运行

另一种情况是,比如我想让主程序运行完就立刻结束,杀死子程序:可以用t.setDaemon(True)

def fuction(i):
    print("我是第%s个进程,开始时间是%s"%(i+1,time.ctime()))
    time.sleep((i+0.5)*2)               #模拟子程序运行随机秒
    print("我是第%s个进程,结束时间是%s"%(i+1,time.ctime()))
threads=[threading.Thread(target=fuction,args=(i,) ) for i in range(5)]

for t in threads:
    t.setDaemon(True)
    t.start()
print("主进程:%s:"%(time.ctime()))

#输出---------------------------------
我是第1个进程,开始时间是Sun Oct 22 19:04:06 2017
我是第2个进程,开始时间是Sun Oct 22 19:04:06 2017
我是第3个进程,开始时间是Sun Oct 22 19:04:06 2017
我是第4个进程,开始时间是Sun Oct 22 19:04:06 2017
我是第5个进程,开始时间是Sun Oct 22 19:04:06 2017
主进程:Sun Oct 22 19:04:06 2017:                 #可以看到主线程完成后,后面就没有子线程了。

一种特殊情况请注意:当并非像上面每个子进程一样都设置t.setDaemon(True)(有的设置有的没有。。)
如:

threads[2].setDaemon(True)   #只设置了第3个和第5个,1,2,4没有设置这只会kill掉第5个子线程
                             #个人猜测,当程序运行完主线程后则会检查剩余的子线程,将最后面的                             
threads[4].setDaemon(True)   #且是setDaemon(True) 子进程删掉。第3个没有kill掉是因为4线程还在运行
for t in threads:            #并且4是默认状态不能被kill的。这时主进程依然在等待4完成而不会
    t.start()                #杀掉剩余进程,当4完成了,就不等待了直接杀掉剩余进程

我们可以这样验证,在线程4结束前看看线程5是否存活:

import tensorflow as tf
import numpy as np
import random
import threading
import time


def fuction(i):
    print("我是第%s个进程,开始时间是%s"%(i+1,time.ctime()))
    time.sleep((i+0.5)*2)               #模拟子程序运行随机秒
    print("我是第%s个进程,结束时间是%s"%(i+1,time.ctime()))
    if i ==3:
        print("我是第4个进程:结束前进程5的状态是:" ,threads[4].is_alive())   #加这一句判断现成物
                                                                            #的存活情况
threads=[threading.Thread(target=fuction,args=(i,) ) for i in range(5)]

#threads[0].setDaemon(True)
#threads[1].setDaemon(True)
threads[2].setDaemon(True)
#threads[3].setDaemon(True)
threads[4].setDaemon(True)

for t in threads:
    t.start()
print("主进程:%s:"%(time.ctime()))

#输出----------------------------------
我是第1个进程,开始时间是Sun Oct 22 19:22:36 2017
我是第2个进程,开始时间是Sun Oct 22 19:22:36 2017
我是第3个进程,开始时间是Sun Oct 22 19:22:36 2017
我是第4个进程,开始时间是Sun Oct 22 19:22:36 2017
我是第5个进程,开始时间是Sun Oct 22 19:22:36 2017
主进程:Sun Oct 22 19:22:36 2017:
我是第1个进程,结束时间是Sun Oct 22 19:22:37 2017
我是第2个进程,结束时间是Sun Oct 22 19:22:39 2017
我是第3个进程,结束时间是Sun Oct 22 19:22:41 2017
我是第4个进程,结束时间是Sun Oct 22 19:22:43 2017
我是第4个进程:结束前进程5的状态是: True        #可以看到,此时线程5还是存活的,但4结束后5就消失了。

最后一种应用时,我们希望主程序等待某几个子线程先执行完后在运行,并且杀死剩余没有完成的程序,可以用setDaemon()、join() 组合的方式:
如:完整运行完第1,2,3线程,之后运行主线程,主线程完成后杀死剩余的子线程:

def fuction(i):
    print("我是第%s个进程,开始时间是%s"%(i+1,time.ctime()))
    time.sleep((i+0.5)*2)               #模拟子程序运行随机秒
    print("我是第%s个进程,结束时间是%s"%(i+1,time.ctime()))
    if i ==3:
        print("我是第4个进程:结束前进程5的状态是:" ,threads[4].is_alive())
threads=[threading.Thread(target=fuction,args=(i,) ) for i in range(5)]

#threads[0].setDaemon(True)
#threads[1].setDaemon(True)
#threads[2].setDaemon(True)
threads[3].setDaemon(True)          #设置第4和5子线程为可以kill的线程
threads[4].setDaemon(True)

for t in threads:
    t.start()
threads[0].join()                  #设置第1,2,3线程阻塞主线程的子线程
threads[1].join()
threads[2].join()
print("主进程:%s:"%(time.ctime()))

#输出--------------------------
我是第1个进程,开始时间是Sun Oct 22 19:32:24 2017
我是第2个进程,开始时间是Sun Oct 22 19:32:24 2017
我是第3个进程,开始时间是Sun Oct 22 19:32:24 2017
我是第4个进程,开始时间是Sun Oct 22 19:32:24 2017
我是第5个进程,开始时间是Sun Oct 22 19:32:24 2017
我是第1个进程,结束时间是Sun Oct 22 19:32:25 2017
我是第2个进程,结束时间是Sun Oct 22 19:32:27 2017
我是第3个进程,结束时间是Sun Oct 22 19:32:29 2017
主进程:Sun Oct 22 19:32:29 2017:                #我们可以看到只完成了第1,2,3线程,然后最后是主线程

这篇文章就到这里,python中子线程的暂停,阻塞,关闭,和唤醒,本人都不是很明确,如有好方法希望大家一起交流。我先写在这里。对于tensorflow中的读取数据线程控制,等我整理在下一篇博客。

    原文作者:axj20
    原文地址: https://segmentfault.com/a/1190000011664213
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞