进程和线程
进程:执行一次程序,有自己的地址空间,内存,数据栈等.
线程(轻量级进程):一般是并发执行的,多个线程可以在一个进程中,共享运行环境.
线程模块:包括_thread,threading和Queue等
threading(比thread功能更完善,支持守护线程)
例1:单线程
# coding=utf-8
from time import ctime, sleep
def music(func):
for i in range(2):
print('I was listening to %s>>%s' % (func,ctime()))
sleep(1)
def move(func):
for i in range(2):
print('I was at the %s>>%s' % (func,ctime()))
sleep(5)
if __name__ == '__main__':
music(u'狮子座')
move(u'阿凡达')
print('all over %s' % ctime())
结果:
I was listening to 狮子座. Wed Nov 21 16:30:29 2018
I was listening to 狮子座. Wed Nov 21 16:30:30 2018
I was at the 阿凡达! Wed Nov 21 16:30:31 2018
I was at the 阿凡达! Wed Nov 21 16:30:36 2018
all over Wed Nov 21 16:30:41 2018
例2:多线程1
#coding=utf-8
import threading
from time import ctime,sleep
def music(func):
for i in range(2):
print('I was listening to %s. %s' % (func,ctime()))
sleep(1)
def move(func):
for i in range(2):
print('I was at the %s! %s' % (func,ctime()))
sleep(5)
threads = []
#创建threads数组,线程t1.使用threading.Thread()方法,在这个方法中调用music方法
#targs方法对music进行传参。 把创建好的线程t1装到threads数组中。
t1 = threading.Thread(target=music,args=(u'狮子座',))
threads.append(t1)
#同样的方式创建线程t2,并把t2装到threads数组
t2 = threading.Thread(target=move,args=(u'阿凡达',))
threads.append(t2)
if __name__ == '__main__':
for t in threads: #通过for循环遍历数组
#setDaemon(True)将线程声明为守护线程,必须在start() 方法调用之前设置,
# 如果不设置为守护线程程序会被无限挂起。
t.setDaemon(True)
t.start() #开始线程活动
print('all over %s' % ctime())
结果:
I was listening to 狮子座. Wed Nov 21 16:57:17 2018
I was at the 阿凡达! Wed Nov 21 16:57:17 2018
all over Wed Nov 21 16:57:17 2018
修改:
if __name__ == '__main__':
for t in threads: #通过for循环遍历数组
#setDaemon(True)将线程声明为守护线程,在start() 方法调用之前设置
t.setDaemon(True)
t.start() #开始线程活动
#join:在子线程完成运行之前,这个子线程的父线程将一直被阻塞
t.join()
print('all over %s' % ctime())
结果:
I was listening to 狮子座. Wed Nov 21 17:05:46 2018
I was at the 阿凡达! Wed Nov 21 17:05:46 2018
I was listening to 狮子座. Wed Nov 21 17:05:47 2018
I was at the 阿凡达! Wed Nov 21 17:05:51 2018
all over Wed Nov 21 17:05:56 201
例3:多线程2
#coning=utf-8
import threading
from time import sleep
from datetime import datetime
loops = [4,2]
date_time_format = '%y-%m-%d %h:%M:%S'
def date_time_str(date_time):
return datetime.strftime(date_time,date_time_format)
def loop(n_loop,n_sec):
print('开始执行线程:',n_loop,date_time_str(datetime.now()),'先休眠',n_sec)
sleep(n_sec)
print('休眠结束',n_loop, date_time_str(datetime.now()))
def main():
print('开始执行线程')
threads=[]
n_loops=range(len(loops))
for i in n_loops:
#第一个函数接方法,第二个函数接元组
t=threading.Thread(target=loop,args=(i,loops[i]))
threads.append(t)
for i in n_loops: #start threads
threads[i].start()
for i in n_loops: # wait for all
threads[i].join() #threads to finish
print('所有线程结束', date_time_str(datetime.now()))
if __name__=='__main__':
main()
结果:
开始执行线程
开始执行线程: 0 18-11-23 Nov:53:39 先休眠 4
开始执行线程: 1 18-11-23 Nov:53:39 先休眠 2
休眠结束 1 18-11-23 Nov:53:41
休眠结束 0 18-11-23 Nov:53:43
所有线程结束 18-11-23 Nov:53:43
所有线程结束 18-11-23 Nov:53:43
例4: 类中的多进程
#coding=utf-8
import threading
from time import ctime,sleep
class MyThread(threading.Thread): #创建MyThread类,用于继承threading.Thread类
def __init__(self,func,args,name=''):
threading.Thread.__init__(self)
self.name = name
self.func = func
self.args = args
def run(self):
self.func(*self.args)
#apply(self.func, self.args) python2用法
def super_play(file,time):
for i in range(2):
print('Start playing:%s>>>%s' %(file,ctime()))
sleep(time)
list = {'狮子座.mp3':3,'阿凡达.mp4':5}
#创建线程
threads = []
files = range(len(list))
for k,v in list.items(): #item() 以列表方式返回,键值由元祖组成
#由于MyThread类继承threading.Thread类,所以可以使用MyThread类来创建线程
t = MyThread(super_play,(k,v),super_play.__name__)
threads.append(t)
if __name__ == '__main__':
#启动线程
for i in files:
threads[i].start()
for i in files:
threads[i].join()
#主线程
print('end:%s' % ctime()
结果:
Start playing:狮子座.mp3>>>Wed Nov 21 17:57:41 2018
Start playing:阿凡达.mp4>>>Wed Nov 21 17:57:41 2018
Start playing:狮子座.mp3>>>Wed Nov 21 17:57:44 2018
Start playing:阿凡达.mp4>>>Wed Nov 21 17:57:46 2018
end:Wed Nov 21 17:57:51 2018