python多线程
import threading import time def music(): print('begin to listen %s' % time.ctime()) time.sleep(3) print('stop to listen %s' % time.ctime()) def game(): print('begin to play %s' % time.ctime()) time.sleep(5) print('stop to play %s' % time.ctime()) if __name__ == '__main__': t1 = threading.Thread(target=music) t1.start() t2 = threading.Thread(target=game) t2.start() t1.join() #等t1线程执行完毕后才执行后面代码 print('ending')
join():在子线程完成运行之前,这个子线程的父线程将一直被阻塞。
守护线程
setDaemon(True):将线程声明为守护线程,必须在start() 方法调用之前设置,当主线程执行完毕时(包括主线程下的所有子线程),守护线程直接终止。
import threading import time def music(): print('begin to listen %s' % time.ctime()) time.sleep(3) print('stop to listen %s' % time.ctime()) def game(): print('begin to play %s' % time.ctime()) time.sleep(5) print('stop to play %s' % time.ctime()) if __name__ == '__main__': t1 = threading.Thread(target=music) t1.start() t2 = threading.Thread(target=game) t2.setDaemon(True) t2.start() print('ending')
全局解释器锁(GIL)
无论你启多少个线程,你有多少个cpu, Python在执行的时候会淡定的在同一时刻只允许一个线程运行,对于计算密集性任务python多线程不能提高效率,但是对于IO密集型任务多线程可以提高效率。
同步锁
加了同步锁的部分相当于串行执行,要等这部分代码执行完成后才执行其它线程。在同一时间只能有一个线程拿到同一把锁
import threading import time def f(): global num lock.acquire() tmp = num time.sleep(0.1) num = tmp - 1 lock.release() num=100 lock = threading.Lock() l = [] for _ in range(100): t = threading.Thread(target=f) t.start() l.append(t) for t in l: t.join() print(num)
死锁
在线程间共享多个资源的时候,如果两个线程分别占有一部分资源并且同时等待对方的资源,就会造成死锁,因为系统判断这部分资源都正在使用,所有这两个线程在无外力作用下将一直等待下去。下面是一个死锁的例子:
import threading,time class myThread(threading.Thread): def doA(self): lockA.acquire() print(self.name,"gotlockA",time.ctime()) time.sleep(3) lockB.acquire() print(self.name,"gotlockB",time.ctime()) lockB.release() lockA.release() def doB(self): lockB.acquire() print(self.name,"gotlockB",time.ctime()) time.sleep(2) lockA.acquire() print(self.name,"gotlockA",time.ctime()) lockA.release() lockB.release() def run(self): self.doA() self.doB() if __name__=="__main__": lockA=threading.Lock() lockB=threading.Lock() threads=[] for i in range(5): threads.append(myThread()) for t in threads: t.start() for t in threads: t.join()#等待线程结束,后面再讲。
递归锁
同一个线程可以拿同一把递归锁多次,没拿一次这把锁的计数器加一,当这把锁的计数器不为0时,其它线程不能拿到这把锁。
import threading,time class myThread(threading.Thread): def doA(self): lock.acquire() print(self.name,"gotlockA",time.ctime()) time.sleep(3) lock.acquire() print(self.name,"gotlockB",time.ctime()) lock.release() lock.release() def doB(self): lock.acquire() print(self.name,"gotlockB",time.ctime()) time.sleep(2) lock.acquire() print(self.name,"gotlockA",time.ctime()) lock.release() lock.release() def run(self): self.doA() self.doB() if __name__=="__main__": lock=threading.RLock() threads=[] for i in range(5): threads.append(myThread()) for t in threads: t.start() for t in threads: t.join()#等待线程结束,后面再讲。
ThreadLocal
import threading # 创建全局ThreadLocal对象: local_school = threading.local() def process_student(): # 获取当前线程关联的student: std = local_school.student print('Hello, %s (in %s)' % (std, threading.current_thread().name)) def process_thread(name): # 绑定ThreadLocal的student: local_school.student = name process_student() t1 = threading.Thread(target= process_thread, args=('Alice',), name='Thread-A') t2 = threading.Thread(target= process_thread, args=('Bob',), name='Thread-B') t1.start() t2.start() t1.join() t2.join()
全局变量local_school就是一个ThreadLocal对象,每个Thread对它都可以读写student属性,但互不影响。你可以把local_school看成全局变量,但每个属性如local_school.student都是线程的局部变量,可以任意读写而互不干扰,也不用管理锁的问题,ThreadLocal内部会处理。
可以理解为全局变量local_school是一个dict,不但可以用local_school.student,还可以绑定其他变量,如local_school.teacher等等。
参考博客
https://www.cnblogs.com/yuanchenqi/articles/6248025.html

浙公网安备 33010602011771号