一.内容回顾
进程是计算机中最小的资源分配单位
进程与进程之间数据隔离,执行过程异步
为什么会出现进程的概念?
为了合理利用cpu,提高用户体验
多个进程是可以同时利用多个cpu的,可以实现并行的效果
僵尸进程
进程 状态码 z/z 僵尸进程 linux
在主进程中控制子进程的方法
子进程对象 = Process (target,args) 在创建的这一刻根本就没有通知操作系统
子进程对象. start() 通知操作系统,开启子进程,异步非阻塞
子进程对象.terminate() 通知操作系统,结束子进程,异步非阻塞
子进程对象.is_alive() 查看子进程是否还活着
子进程对象.join() 阻塞,直到子进程结束
子进程对象.join(timeout = 10) 阻塞最多10s,期间子进程如果结束就结束阻塞,如果没结束10s之后也结束阻塞
# 守护进程 # 守护进程是一个子进程 # 守护进程会在主进程代码结束之后才结束 # 为什么会这样? # 由于主进程必须要回收所有的子进程的资源 # 所以主进程必须在子进程结束之后才能结束 # 而守护进程就是为了守护主进程存在的 # 不能守护到主进程结束,就只能退而求其次,守护到代码结束了 # 守护到主进程的代码结束,意味着如果有其他子进程没有结束,守护进程无法继续守护 # 解决方案 : 在主进程中加入对其他子进程的join操作,来保证守护进程可以守护所有主进程和子进程的执行 # 如何设置守护进程 # 子进程对象.daemon = True 这句话写在start之前
# 锁 # 为什么要用锁? # 由于多个进程的并发,导致很多数据的操作都在同时进行 # 所以就有可能产生多个进程同时操作 : 文件数据库 中的数据 # 导致数据不安全 # 所以给某一段修改数据的程序加上锁,就可以控制这段代码永远不会被多个进程同时执行 # 保证了数据的安全 # Lock 锁(互斥锁) # 锁实际上是把你的某一段程序变成同步的了,降低了程序运行的速度,为了保证数据的安全性 # 没有数据安全的效率都是耍流氓
信号量
# 对于锁 保证一段代码同一时刻只能有一个进程执行 # 对于信号量 保证一段代码同一时刻只能有n个进程执行 # 流量控制 # 10个进程
from multiprocessing import Semaphore sem = Semaphore(4) sem.acquire() print('拿走一把钥匙1') sem.acquire() print('拿走一把钥匙2') sem.acquire() print('拿走一把钥匙3') sem.acquire() print('拿走一把钥匙4') sem.release()#释放信号
sem.acquire() print('拿走一把钥匙5')
信号量Semaphore是同时允许一定数量的线程更改数据
信号量同步基于内部计数器,每调用一次acquire(),计数器减1;每调用一次release(),计数器加1.当计数器为0时,acquire()调用被阻塞。
import time import random from multiprocessing import Process,Semaphore def ktv(name,sem): sem.acquire() print("%s走进了ktv"%name) time.sleep(random.randint(5,10)) print("%s走出了ktv" % name) sem.release() if __name__ == '__main__': sem = Semaphore(4) for i in range(100): p = Process(target=ktv,args = ('name%s'%i,sem)) p.start() name1走进了ktv name0走进了ktv name3走进了ktv name4走进了ktv name1走出了ktv name2走进了ktv name3走出了ktv
事件Event 事件类
e = Event()
e为事件对象,事件本身就带着标识:False
wait 阻塞
它的阻塞条件是 对象标识为False
结束阻塞条件是 对象标识为True
对象的标识相关的
set 将对象的标识设置为True
clear 将对象的标识设置为False
is_set 查看对象的标识是否为True
import time
import random
from multiprocessing import Event,Process
def traffic_light(e):
print('