python3中支持多线程的目前有threading和Queue模块,之前的thread模块已经从最新的python3中移除,找不到。相比于以前的thread模块,threading模块更安全拥有更多的同步机制,可以提供更多的方法。
threading模块中支持守护线程,守护线程是一个等待客户端请求服务的服务器,如果没有客户端的请求,守护线程就是空闲的。若把一个守护线程设置为守护线程,那么这个线程就是不重要的,进程退出的时候不需要等待这线程执行完成。在主线程准备退出时候,不需要等待某些子线程完成,那么就可以把这些子线程设置为守护线程标记,为True表示该线程不重要,或者是该线程是为了等待客户端的请求而不做任何其他的事情。
在threading模块中我们主要使用thread类,thread类有很多的方法创建线程,主要有:
1.创建thread的实例,传递一个函数
2.创建thread的实例,传递一个可调用的类实例
3.派生thread的子类,并且创建子类的实例
(1)在单线程条件下:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Thu Jan 11 16:51:18 2018
@author: lisir
"""
from time import sleep
from time import ctime
def loop0():
print('start loop 0 at :', ctime())
sleep(4)
print('loop 0 done at :', ctime())
def loop1():
print('start loop 1 at :', ctime())
sleep(2)
print('loop 1 done at :', ctime())
def main():
print('starting at: ', ctime())
loop0()
loop1()
print('all done at :', ctime())
if __name__ == '__main__':
main()
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Thu Jan 11 16:51:18 2018
@author: lisir
"""
import threading
from time import sleep
from time import ctime
loops = [4, 2]
def loop(nloop, nsec):
print('start loop :', nloop, ' at: ', ctime())
sleep(nsec)
print('loop ', nloop, ' done at : ', ctime())
def main():
print('starting at: ', ctime())
threads = []
nloops = range(len(loops))
for i in nloops:
t = threading.Thread(target=loop,args=(i, loops[i]))
threads.append(t)
# start threads
for i in nloops:
threads[i].start()
# wait for all threads to finish
for i in nloops:
threads[i].join()
print('all done at :', ctime())
if __name__ == '__main__':
main()
(3)创建thread的实例,传递一个可调用的类实例
这个方法中创建一个ThreadFunc类,其构造函数设定该类的函数参数,函数自身,函数名字符串。当实例化thread类对象时,调用类ThreadFunc,此时就回去调用__call__()这个方法,我们已经有要用到的参数,所以不需要将其传递给thread()的构造函数,直接调用即可。
(4)派生thread的子类,并且创建子类的实例
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Thu Jan 11 16:51:18 2018
@author: lisir
"""
import threading
from time import sleep
from time import ctime
loops = [4, 2]
class 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)
def loop(nloop, nsec):
print('start loop :', nloop, ' at: ', ctime())
sleep(nsec)
print('loop ', nloop, ' done at : ', ctime())
def main():
print('starting at: ', ctime())
threads = []
nloops = range(len(loops))
for i in nloops:
t = MyThread(loop, (i, loops[i]), loop.__name__)
threads.append(t)
# start threads
for i in nloops:
threads[i].start()
# wait for all threads to finish
for i in nloops:
threads[i].join()
print('all done at :', ctime())
if __name__ == '__main__':
main()
综合以上的方法练习一个单线程和多线程执行对比程序:
首先我们吧上面的第4个方法写成一个模块myThread.py的程序,在接下来的程序中去调用
myThread.py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Thu Jan 11 16:51:18 2018
@author: lisir
"""
# myThread.py
import threading
from time import sleep
from time import ctime
loops = [4, 2]
class MyThread(threading.Thread):
def __init__(self, func, args, name=''):
threading.Thread.__init__(self)
self.name = name
self.func = func
self.args = args
def getResult(self):
return self.res
def run(self):
print('starting ', self.name, ' at ', ctime())
self.res = self.func(*self.args)
print(self.name, ' done at ', ctime())
执行程序:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Thu Jan 11 16:51:18 2018
@author: lisir
"""
from myThread import MyThread
from time import sleep
from time import ctime
def fib(x):
sleep(0.005)
if x < 2:
return 1
return (fib(x-2) + fib(x-1))
def fac(x):
sleep(0.1)
if x < 2:
return 1
return (x * fac(x-1))
def sum(x):
sleep(0.1)
if x < 2:
return 1
return (x + sum(x-1))
funcs = [fib, fac, sum]
n =12
def main():
nfuncs = range(len(funcs))
print('starting at :', ctime())
print("*********single thread***********")
for i in nfuncs:
print('starting ', funcs[i].__name__, 'at:',ctime())
print(funcs[i](n))
print(funcs[i].__name__, 'finish at :', ctime())
print("*********multiple thread***********")
threads = []
for i in nfuncs:
t = MyThread(funcs[i], (n,), funcs[i].__name__)
threads.append(t)
for i in nfuncs:
threads[i].start()
for i in nfuncs:
threads[i].join()
print(threads[i].getResult())
print('all done at :', ctime())
if __name__ == '__main__':
main()