本人初学者开始第一篇博客,记录学习的点点滴滴,以作为备忘录,也希望能同大家一起分享。有理解错误的地方希望大家指正。 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中的读取数据线程控制,等我整理在下一篇博客。