1. 概念
同步概念:协同步调,按预定的先后次序运行
并发:不同时运行(线程)
并行:同时运行(进程)
同步原语:1.互斥锁,2.信号量原语,3.queue队列
上下文管理器:with
死锁:1.通过银行家算法解决,2.添加超时时间
模块:threading.Thread
线程池:创建线程需要经过启动、销毁和运行3个过程。创建和用完的线程放入一个容器中,用户下次使用无须再开辟一个新进程。节约开辟新线程时间,提高响应速度,也便于对线程进行管理。
守护线程:当主线程退出时,所有子线程都将终止,不管它们是否仍在工作。标记值为True时,表示线程不重要。注意需要在启动线程之前设置。例如在服务器线程运行在一个无限循环里等待用户请求,当关闭进程即不会管该线程状态直接退出,正常python程序是在所有非守护线程退出之后才退出。进程完成后不会死掉。
join(timeout=None):直至启动的线程终止之前一直挂起;除非给出了timeout
GIL锁(全局解析锁)对多线程的影响:任意时刻只有一个线程会被解析器执行。对于IO密集型任务,线程在等待的时候会释放GIL,则多线程对此任务有很大效率提高。对于计算(cpu)密集型,由于不断获取线程,释放,反而会降低效率。
2. 实例
1.创建Thread实例,传入一个函数
import threading
from time import sleep, ctime
loops = [4,2]
def loop(nloop, nsec):
print('start loop {} at: {}'.format(nloop, ctime()))
sleep(nsec)
print('loop {} done at {}'.format(nloop, ctime()))
def main():
print('starting at:{}'.format(ctime()))
threads = []
nloops = range(len(loops))
for i in nloops:
t = threading.Thread(target=loop, args=(i, loops[i]))
threads.append(t)
for i in nloops: # 同时启动线程
threads[i].start()
for i in nloops:
threads[i].join()
print('all done at {}'.format(ctime()))
if __name__ == '__main__':
main()
2.创建Thread实例,传入一个可调用的类实例
import threading
from time import sleep, ctime
loops = [4, 2]
class ThreadFunc(object):
def __init__(self, func, args, name=''):
self.name = name
self.func = func
self.args = args
def __call__(self):
self.func(*self.args)
def loop(nloop, nsec):
print('start loop {} at {}'.format(nloop, ctime()))
sleep(nsec)
print('loop {} done at {}'.format(nloop, ctime()))
def main():
print('starting at {}'.format(ctime()))
threads = []
nloops = range(len(loops))
for i in nloops:
t = threading.Thread(target=ThreadFunc(loop, (i, loops[i]), loop.__name__))
threads.append(t)
for i in nloops:
threads[i].start()
for i in nloops:
threads[i].join()
print('all done at {}'.format(ctime()))
if __name__ == '__main__':
main()
3.派生Thread的子类,并创建子类的实例
import threading
from time import sleep, 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 {} at {}'.format(nloop, ctime()))
sleep(nsec)
print('loop {} done at {}'.format(nloop, ctime()))
def main():
print('starting at {}'.format(ctime()))
threads = []
nloops = range(len(loops))
for i in nloops:
t = MyThread(loop, (i, loops[i]), loop.__name__)
threads.append(t)
for i in nloops:
threads[i].start()
for i in nloops:
threads[i].join()
print('all done at {}'.format(ctime()))
if __name__ == '__main__':
main()
3. 锁
acquire()和release()