多线程
多线程
基于并发编程
进程的定义:是操作系统可以调度已经进行资源分配的基本单位,是一个资源单位,其中包含了运行这个程序所需的资源
线程的定义:是操作系统可以运算调度的最小单位,是真正的执行单位,其包含在进程当中,一个线程就是一条固定的控制流程
两者的关系:进程可以包含多个线程,同一进程中的线程共享进程内的资源
特点:系统会为每个进程自动创建一条线程,称之为主线程,后续通过代码开启的线程称之为子线程
对照表:
进程 | 线程 |
---|---|
进程是一个资源单位 | 是一个执行单位 |
创建开销——————> | 创建开销 |
多个进程之间是相互隔离的 | 线程之间是共享进程内的所有资源的 |
进程对于硬件资源是竞争关系 | 线程是协作关系,-->流水线上的员工 |
开启进程消耗的资源很大(1000就奔溃) | 开启非常快 |
进程之间的有层级关系 | 线程是平等的 |
进程好比作车间 | 线程好比做流水线 |
为什么要用线程直接用进程岂不是就可以
1:有多个任务要并发处理
2:当要并发处理的让你无有很多时,不能使用进程,进程资源开销太大,线程开销资源很小,适合用于非常多的情况
线程的使用
方式一:直接实例化Thread类
from threading import Thread
def task():
print('子线程 run')
与进程的不同之处: 不需要加判断+开启线程的代码放哪里都可以
t=Thread(target=task)
t.start()
print('over')
方法二:继承Thread类
class Mythread(Thread):
def run(self):
#把在子线程中的执行代码放入run中
print('zi run')
mt =Mythread()
me.start()
print('over')
线程的安全问题
只要并发了访问同一资源一定会产生安全问题,解决方案和多进程一致,就是给操作公共资源代码加锁就完事
from threading import Lock,Thread
import time
a=10
l=Lock()
def task():
global a
l.acquire()
temp=a
time.sleep(0.2)
a=temp-1
l.release()
lis=[]
for i in range(10):
t=Thread(targer=task)
t.start()
lis.append(t)
for t in lis:
t.join()
print('a')
守护进程
一个线程a 设置为b的守护线程,a会随着b的结束而结束
默认的情况下,主线程即使代码执行完毕,也会等待所有非守护线程完毕后程序才能结束,因为多个线程之间是协作关系
from threading import Thread
import time
def task():
print('妃子 start')
time.sleep(5)
print('妃子 over')
def task2():
print('皇后 start')
time.sleep(5)
print('皇后 over')
print('主 satrt')
t=Thred(target=task)
t.daemon() =True
t.start()
t2= Thread(target=task)
t2.start()
print('主 over')
打印结果:
主 start
妃子 start
皇后 start
主 over
皇后 over
线程中的常用属性和方法
from threading import Thread,currentThread,enumerate,activecount
import time
"""
t=Thread()
t=start()
t.join()
t.is_alive()
t.isAlive()
t.ident #线程的标志符
t.daemon()
获取当前线程的对象
print(currentThread())
t=Thread(target=lambda:print(currentThread()))
t.start()
"""
t=Thread(taeget=lambda:time.sleep(1))
t.start()
t=Thread(target=lambda:time.sleep(1))
t.start()
t.join()
#获取正在运行的所有线程对象,是一个列表
print(enumerate())
#存活的线程数量
print(activeCount())
程序的道路上一去不复返