多线程threading详解
1 import time from threading import Thread,current_thread def demo(): print(f'子线程开始,线程名字:{current_thread().name}') time.sleep(2) print(f'子线程结束,线程名字:{current_thread().name}') if __name__ == '__main__': print('主线程开始...') threads = [Thread(target=demo) for _ in range(3)] for t in threads: t.start() for t in threads: t.join() print('主线程结束...')
2
import time from threading import Thread,current_thread def demo(): print(f'子线程开始,线程名字:{current_thread().name}') time.sleep(2) print(f'子线程结束,线程名字:{current_thread().name}') if __name__ == '__main__': print('主线程开始...') threads = [Thread(target=demo) for _ in range(3)] n = 0 for t in threads: n += 1 if n == 1: t.setDaemon(True) t.start() print('主线程结束...')
3
通过daemon参数设置守护线程,daemon默认是None
import time from threading import Thread,current_thread def demo(): print(f'子线程开始,线程名字:{current_thread().name}') time.sleep(2) print(f'子线程结束,线程名字:{current_thread().name}') if __name__ == '__main__': print('主线程开始...') threads = [Thread(target=demo,daemon=True) for _ in range(3)] for t in threads: t.start() print('主线程结束...')
4
如果子线程同时存在守护线程和非守护线程, 结果同setDaemon
import time from threading import Thread,current_thread def demo(): print(f'子线程开始,线程名字:{current_thread().name}') time.sleep(2) print(f'子线程结束,线程名字:{current_thread().name}') if __name__ == '__main__': print('主线程开始...') threads1 = Thread(target=demo,daemon=True) threads2 = Thread(target=demo) threads1.start() threads2.start() print('主线程结束...')
5
互斥锁(Lock),同一时刻仅能有一个访问者对其进行访问.
先看一个例子,假设有一个数字,实始是0,一个线程做加法,每次加1,加一百万次,同时,一个线程做减法,每次减1,减一百万次,做完后这个数字应该是0,结果却不一定
from threading import Thread NUM = 0 def add(): global NUM for i in range(1000000): NUM += 1 def sub(): global NUM for i in range(1000000): NUM -= 1 if __name__ == '__main__': threads_add = Thread(target=add) threads_sub = Thread(target=sub) threads_add.start() threads_sub.start() threads_add.join() threads_sub.join() print(f'最终账户余额:{NUM}')
6
在同一个进程中的多线程是共享资源的,即共享全局变量,线程之间也是进行随机调度,每次做加、减时,取到的NUM是不定的,随机的,所以会导致结果出现异常,此时需要引入锁,来保证线程安全。
锁的意思是,在同一时间内,只有一个线程可以操作全局变量,即A取到NUM时,B会处于等待状态,当A交出NUM时,B才能取到NUM。
from threading import Thread,Lock NUM = 0 def add(lock): global NUM for i in range(1000000): lock.acquire() NUM += 1 lock.release() def sub(lock): global NUM for i in range(1000000): lock.acquire() NUM -= 1 lock.release() if __name__ == '__main__': lock = Lock() threads_add = Thread(target=add,args=(lock,)) threads_sub = Thread(target=sub,args=(lock,)) threads_add.start() threads_sub.start() threads_add.join() threads_sub.join() print(f'最终账户余额:{NUM}') 7 支持使用with语句来实现加锁、解锁。
from threading import Thread,Lock NUM = 0 def add(lock): global NUM with lock: for i in range(1000000): NUM += 1 def sub(lock): global NUM with lock: for i in range(1000000): NUM -= 1 if __name__ == '__main__': lock = Lock() threads_add = Thread(target=add,args=(lock, )) threads_sub = Thread(target=sub,args=(lock, )) threads_add.start() threads_sub.start() threads_add.join() threads_sub.join() print(f'最终账户余额:{NUM}')
参考