并发:看上去一起执行。(任务数>核数)
并行:实际上一起执行。
一:创建子进程:os.fork() 。 用判断语句,if:else:父进程子进程一起执行。
fork函数在windows不可以运行。每调用一次,进程数*2
基本不用,属于底层。
二:windows:from multiprocessing import Process ,主进程等待子进程结束。
p =Process(target = func) ,p.start()
三:进程池:Pool
作用:缓冲 ,相当于提前创建好池子(包含最大进程数),需要时候调用(在池子里添加任务) p = pool(n),p.apply_async(xxx) 非阻塞方式
特点:进程池的主进程不会等着子进程,主进程一般用来等待,任务都是子进程做的,不需要每次创建池子,提高效率。
解决方案:pool.close() 关闭,不再添加新任务 + pool.join() 等待子进程结束。
例如:池子3个进程,添加10个任务,不会阻塞,池子里的3个进程轮流做任务。
阻塞方式:p.apply(),一个一个执行,基本不用
---------------------------进程通信-------------------------------
进程间通信:用Queue,队列。 因为进程和进程之间默认没有关联。
用Queue创建的通信,只能在Process创建的进程里用
如果在进程池中创建的任务要实现通信,用Manager.Queue() 初始化才可以用。
先进先出:队列,先进后出:栈
----------------------------多线程------------------------------------
一个程序有一个进程,这个进程有个主线程,还可以有若干个子线程。主线程执行完了,也不会立即结束,主线程的主要任务就是会等待子线程。
多个线程执行同一个函数,不会有任何问题。
创建线程方式一:from threading import Thread, t = Thread(target = xxx) , t.start(),t.join()
创建线程方式二:import threading , 定义新的类继承 Thread
执行顺序:操作系统说了算
全局变量:多进程不共享全局变量,全局变量个人是个人的。但是多线程里面共享全局变量。
进程和线程区别:列表(可变数据类型)当做参数给线程,线程间数据共享。
互斥锁:用一个全局变量时候,用轮询效率低,所以用互斥锁。
作用保证多线程对同一资源竞争时候,只有一个能上锁,其他都卡住,解锁后其他线程一起抢上锁。 lock = Lock()
acquire上锁,release解锁。 对必须加锁的加锁。(相当于通知方式)
不管是进程还是线程,函数里面(非全局变量)不共享,个人是个人的。
死锁:两线程分别占有一部分资源并同时等待对方的资源,会造成死锁。
解决方法:设置超时时间。
------------------------同步-----------------------
同步:协同步调,有规律
异步:不固定顺序
生产者与消费者模式:解决解耦,用到queue
函数需要用到其他函数定义的变量:1,可以传参数 2,全局变量。
用ThreadLocal,(类似于全局字典),
一个函数想要得到另一个函数的值:1,return返回 2,全局变量。
网友评论