线程
1.什么是线程?
进程其实不是一个执行单位,进程是一个资源单位
每个进程自带一个线程,线程才是cpu的执行单位
线程-->代码的执行过程
进程-->资源的申请与销毁的过程
2.为何用线程:
实现并发
3.进程vs线程
①多个进程内存空间彼此隔离
同一进程下的多个线程共享该进程的内存空间
②造线程的速度要远远快于造进程
4.开启线程的两种方法
from threading import Thread import time # 方法一 def task(name): print('%s is running' % name) time.sleep(3) print('done') if __name__ == '__main__': t = Thread(target=task, args=('线程',)) t.start() print('主') #方法二 class Mythread(Thread): def run(self): print('%s is running' % self.name) time.sleep(3) print('done') if __name__ == '__main__': t = Mythread() t.run() print('主')
5.守护线程
守护线程会在该进程内所有非守护线程结束才跟着结束,即守护整个进程的运行周期(所有的非守护线程都运行结束)
6.互斥锁
同一进程下的线程会共用进程的内存空间,当线程中有操作数据的代码时,并发地执行会对数据安全性造成威胁,所以需要牺牲效率来加锁提高数据安全性
7.死锁现象和递归锁
# 死锁现象 from threading import Thread,Lock,active_count import time mutexA = Lock() mutexB = Lock() class MyThread(Thread): def run(self): self.f1() self.f2() def f1(self): mutexA.acquire() print("A") mutexB.acquire() print("B") mutexB.release() mutexA.release() def f2(self): mutexB.acquire() print("A") time.sleep(1) mutexA.acquire() print("B") mutexA.release() mutexB.release() if __name__ == '__main__': for i in range(10): t = MyThread() t.start() print(active_count())
死锁:t1先执行,执行f1时没有人和他抢锁,运行完f1释放A,B锁后,其他在A锁外等的线程强到A锁,而此时t1又马上执行f2,抢到B锁,这样就有形成两个线程各自拿着对方所需要的锁的情况,就造成了死锁现象(Lock)
递归锁:可以多次锁,会标记次数,所有标记都解锁后才能解锁,解决了死锁现象(RLock)
信号量
相当于可以设置数量的互斥锁,Semaphore