进程:资源单位python
线程:执行单位安全
线程与进程都是虚拟的概念,为了更好的表达某种事物app
注意:开启一个进程,必定会自带一个线程,线程才是真正的执行者ui
节省资源的占用线程
开启进程:code
一、产生一个内存空间,申请一块资源对象
二、会自带一个主线程进程
三、开启子进程的速度要比开启子线程的速度慢内存
开启线程:资源
一、一个进程内能够开启多个线程,从进程的内存空间中申请执行单位
二、节省资源
开启几个进程就会开辟几个内存空间,开辟几个线程是在同一个内存空间中申请几个执行单位
同进程的使用类似,调用的是Thread生成对象obj,经过obj.start()开启线程
from threading import Thread import time # 方式1:直接调用 num = 100 def task(): global num num = 200 print('开启子线程') time.sleep(1) print('子线程结束') if __name__ == '__main__': t = Thread(target=task) t.start() print('主进程(主线程)结束') # 子线程要比子进程开启快 # 开启子线程 # 主进程(主线程)结束 # 子线程结束
from threading import Thread import time num = 10 # 方式2:定义类,并重写run方法 class Mythread(Thread): # 重写run方法 def run(self): print('开启子线程') time.sleep(1) print('子线程结束') if __name__ == '__main__': t = Mythread() # 建立子线程 t.start() # 让子线程结束后主进程才结束 t.join() print('主进程(主线程)结束') # 开启子线程 # 子线程结束 # 主进程(主线程)结束
当主线程结束后,子线程也当即结束,并回收,经过 obj.daemon = True 定义在obj.start() 以前设置
from threading import Thread # 当前线程 from threading import current_thread import time num = 10 def task(): global num num = 20 print('开启子线程') time.sleep(1) print('子线程结束') if __name__ == '__main__': t = Thread(target=task) t.daemon = True t.start() # current_thread().name查看当前线程名 print(f'主进程(主线程)结束{current_thread().name}') # 开启子线程 # 主进程(主线程)结束MainThread
互斥锁是用来保证数据读写安全的,在修改同一个数据时,同一时间只能有一个任务能够进行修改,即串行的修改,保证数据安全
from threading import Thread from threading import Lock import time lock = Lock() num = 10 def task(): global num lock.acquire() time.sleep(1) num += 1 lock.release() if __name__ == '__main__': list1 = [] for i in range(10): t = Thread(target=task) t.start() list1.append(t) for t in list1: t.join() print(num) # 20
每个线程的从生成到消亡也是须要时间和资源的,太多的线程会占用过多的系统资源(内存开销,cpu开销),并且生成太多的线程也是须要时间的,极可能会得不偿失 ,线程池是用来限制每次线程的数量
from concurrent.futures import ThreadPoolExecutor import time # 每次线程的数量为10 pool = ThreadPoolExecutor(10) def task(line): print(line) time.sleep(5) if __name__ == '__main__': for line in range(100): pool.submit(task, line)