赞
踩
顾名思义,就是正在运行中的程序。是操作系统中分配任务的最小基本单元;
线程是进程中执行运算的最小单位,是进程中的一个实体,是被系统独立调度和分派的基本单位。线程自己不拥有系统资源;但它可与同属一个进程的其它线程共享进程所拥有的全部资源。一个线程可以创建和撤消另一个线程,同一进程中的多个线程之间可以并发执行。
1、进程是操作系统分配任务的基本单位,进程是python中正在运行的程序;当我们打开了1个浏览器时就是开始了一个浏览器进程;
线程是进程中执行任务的基本单元(执行指令集),一个进程中至少有一个线程、当只有一个线程时,称为主线程
2、线程的创建和销毁耗费资源少,进程的创建和销毁耗费资源多;线程很容易创建,进程不容易创建
3、线程的切换速度快,进程慢
4、一个进程中有多个线程时:线程之间可以进行通信;一个进程中有多个子进程时,进程与进程之间不可以相互通信,如果需要通信时,就必须通过一个中间代理实现,Queue、Pipe。
5、多进程可以利用多核cpu,多线程不可以利用多核cpu
6、一个新的线程很容易被创建,一个新的进程创建需要对父进程进行一次克隆
7、多进程的主要目的是充分使用CPU的多核机制,多线程的主要目的是充分利用某一个单核
多进程中,异步执行任务时,CPU内存空间不一致,但是资源数据是主进程中拷贝的;即一个新的进程创建需要对父进程进行一次克隆
进程池:可以提供指定数量的进程给用户使用,即当有新的请求提交到进程池中时,如果池未满,则会创建一个新的进程用来执行该请求;反之,如果池中的进程数已经达到规定最大值,那么该请求就会等待,只要池中有进程空闲下来,该请求就能得到执行。
1、当进程数过多时,用于限制同时执行的进程数
2、自动的释放资源,节省内存空间
3、提高效率,节省开辟进程和开辟内存空间的时间及销毁进程的时间
import os import time from multiprocessing import Process,Pool number=100 def func(name): print(f'子进程的id:{os.getpid()},子进程的名称{name}') for i in range(3): global number number+=1 print(number) time.sleep(1) if __name__ == '__main__': print(f'主进程的id:{os.getpid()}') p_collects=Pool(5) p_collects.apply_async(func,args=('process-1',)) p_collects.apply_async(func,args=('process-2',)) p_collects.close() #todo 把当前的进程池关掉,不允许去创建新的进程了 p_collects.join() print('主线执行完毕') print(number)
主进程的id:25124
子进程的id:19928,子进程的名称process-1
101
102
103
子进程的id:27500,子进程的名称process-2
101
102
103
主线执行完毕
100
CPU密集型(计算密集型):计算圆周率、浮点运算、对视频进行高清解码
IO密集型:涉及到网络、磁盘IO的任务都是IO密集型任务,Web应用
多进程的主要目的是充分使用CPU的多核机制
多线程的主要目的是充分利用某一个单核
GIL 是python的全局解释器锁,同一进程中假如有多个线程运行,一个线程在运行python程序的时候会霸占python解释器(加了一把锁即GIL),使该进程内的其他线程无法运行,等该线程运行完后其他线程才能运行。如果线程运行过程中遇到耗时操作,则解释器锁解开,使其他线程运行。所以在多线程中,线程的运行仍是有先后顺序的,并不是同时进行。
保证同一个时刻只有一个线程在运行,所以python多线程并不是并行的,是并发的
对于IO密集型全局解析器锁的存在并不会提高执行的速度
即使存在GIL 在有IO等待操作的程序中,还是多线程快,当然没有资源等待的还是单线程快(科学计算,累加)
全局解析器锁(GIL)加在了全局了,没有加到我所想要的位置,加到什么位置不是我们决定的;
包括修改资源的程序和非修改资源的程序,如果出现在修改资源的相关代码上,肯定会出现脏数据。
同步锁:来获取一把互斥锁。互斥锁就是对共享数据进行锁定,保证同一时刻只有一个线程操作数据,是数据级别的锁。
GIL锁是解释器级别的锁,保证同一时刻进程中只有一个线程拿到GIL锁,拥有执行权限。
import threading num=0 def work(): global num for i in range(1000000): num+=1 print('work',num) def work1(): global num for i in range(1000000): num+=1 print('work1',num) if __name__ == '__main__': t1=threading.Thread(target=work) t2=threading.Thread(target=work1) t1.start() t2.start() t1.join() t2.join() print('主线程执行结果',num)
执行结果:明显数据混乱了
work work1 16347351376208
主线程执行结果 1634735
说明:
代码中:num+=1,可以拆解为
num=100
100+1
num=101
同步锁这3行代码执行完毕了才会释放锁
from threading import Lock import threading num=0 def work(): global num for i in range(1000000): with lock: num+=1 print('work',num) def work1(): global num for i in range(1000000): with lock: num+=1 print('work1',num) if __name__ == '__main__': lock=Lock() t1=threading.Thread(target=work) t2=threading.Thread(target=work1) t1.start() t2.start() t1.join() t2.join() print('主线程执行结果',num)
work 1845334work1 2000000
主线程执行结果 2000000
from threading import Lock import threading num=0 def work(): global num for i in range(1000000): lock.acquire() num+=1 lock.release() print('work',num) def work1(): global num for i in range(1000000): lock.acquire() num += 1 lock.release() print('work1',num) if __name__ == '__main__': lock=Lock() t1=threading.Thread(target=work) t2=threading.Thread(target=work1) t1.start() t2.start() t1.join() t2.join() print('主线程执行结果',num)
workwork1 1921583
2000000
主线程执行结果 2000000
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。