博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
僵尸进程与孤儿进程 互斥锁 进程之间的通信
阅读量:5173 次
发布时间:2019-06-13

本文共 5081 字,大约阅读时间需要 16 分钟。

僵尸进程与孤儿进程

基于unix环境(linux, macOS)

​ 主进程需要等待子进程结束之后, 主进程才结束

主进程时刻监测子进程的运行状态, 当子进程结束之后, 一段时间之内, 将子进程进行回收

为什么主进程不在子进程结束后马上对其回收呢?

​ 主进程与子进程是异步关系, 主进程无法马上捕获子进程什么时候结束

​ 如果子进程结束之后, 马上在内存中释放资源, 主进程就没有办法监测子进程的状态了

unix针对于上面的问题, 提供了一个机制

​ 所有的子进程结束之后, 立马会释放掉文件的操作链接, 内存的大部分数据, 但是会保留一些内容: 进程号, 结束时间, 运行状态. 等待主进程监测, 回收.

僵尸进程

​ 所有的子进程结束之后, 在被主进程回收之前, 都会进入僵尸进程状态

僵尸进程有无危害

​ 如果父进程不对僵尸进程进行回收(wait/waitpid), 产生大量的僵尸进程, 这样就会占用内存, 占用进程pid号

僵尸进程如何解决

​ 父进程产生了大量子进程, 但是不回收, 这样就会形成大量的僵尸进程, 解决方式就是直接杀死父进程, 将所有的僵尸进程变成孤儿进程, 由init进行回收

孤儿进程

​ 父进程由于某种原因结束了, 但是你的子进程还在运行中, 这样你的这些子进程就成了孤儿进程, 你的父进程如果结束了, 你的所有的孤儿进程就会被init进程的回收, init就变成了你的父进程, 对你进行回收

互斥锁

​ 三个同事, 同时用一个打印机打印内容.

​ 三个进程模拟三个同事, 输出平台模拟打印机.

​ 互斥锁:

​ 可以公平性的保证顺序以及数据的安全

# 版本一from multiprocessing import Processimport timeimport randomimport osdef task1():    print(f"{os.getpid()}开始打印了")    time.sleep(random.randint(1, 3))    print(f"{os.getpid()}打印结束了")def task2():    print(f"{os.getpid()}开始打印了")    time.sleep(random.randint(1, 3))    print(f"{os.getpid()}打印结束了")def task3():    print(f"{os.getpid()}开始打印了")    time.sleep(random.randint(1, 3))    print(f"{os.getpid()}打印结束了")if __name__ == '__main__':    p1 = Process(target=task1)    p2 = Process(target=task2)    p3 = Process(target=task3)    p1.start()    p2.start()    p3.start()"""188412开始打印了188408开始打印了188388开始打印了188412打印结束了188388打印结束了188408打印结束了"""# 现在是所有的进程都并发的抢占打印机,# 并发是以效率优先的, 但是目前我们的需求: 顺序优先# 多个进程共抢一个资源时, 要保证顺序优先: 串行, 一个一个来
# 版本二from multiprocessing import Processimport timeimport randomimport osdef task1():    print(f"{os.getpid()}开始打印了")    time.sleep(random.randint(1, 3))    print(f"{os.getpid()}打印结束了")def task2():    print(f"{os.getpid()}开始打印了")    time.sleep(random.randint(1, 3))    print(f"{os.getpid()}打印结束了")def task3():    print(f"{os.getpid()}开始打印了")    time.sleep(random.randint(1, 3))    print(f"{os.getpid()}打印结束了")if __name__ == '__main__':    p1 = Process(target=task1)    p2 = Process(target=task2)    p3 = Process(target=task3)    p1.start()    p1.join()    p2.start()    p2.join()    p3.start()    p3.join()"""160876开始打印了160876打印结束了188264开始打印了188264打印结束了188328开始打印了188328打印结束了"""# 我们利用join, 解决串行的问题, 保证了顺序优先, 但是这个谁先谁后是固定的.# 这样不合理, 你在争抢同一个资源的时候, 应该是先到先得, 保证公平
# 版本三from multiprocessing import Processfrom multiprocessing import Lockimport timeimport randomdef task1(p, lock):    lock.acquire()    print(f"{p}开始打印了")    time.sleep(random.randint(1, 3))    print(f"{p}打印结束了")    lock.release()def task2(p, lock):    lock.acquire()    print(f"{p}开始打印了")    time.sleep(random.randint(1, 3))    print(f"{p}打印结束了")    lock.release()def task3(p, lock):    lock.acquire()    print(f"{p}开始打印了")    time.sleep(random.randint(1, 3))    print(f"{p}打印结束了")    lock.release()if __name__ == '__main__':    mutex = Lock()    p1 = Process(target=task1, args=("p1", mutex))    p2 = Process(target=task2, args=("p2", mutex))    p3 = Process(target=task3, args=("p3", mutex))    p1.start()    p2.start()    p3.start()"""p1开始打印了p1打印结束了p2开始打印了p2打印结束了p3开始打印了p3打印结束了"""

1730033-20190821221654718-787909657.png

lock 与 join 的区别

共同点

​ 都可以把并发变成串行, 保证了顺序

不同点

​ join 认为设定顺序, lock 让其争抢顺序, 保证了公平性

进程之间的通信

​ 进程在内存级别是隔离的, 但是文件在磁盘上

1.基于文件通信

​ 利用抢票系统讲解

# 抢票系统# 1. 先可以查票, 查询余票数.    并发# 2. 进行购买, 向服务端发送请求, 服务端接收请求, 在后端将票数-1, 返回到前端           串行from multiprocessing import Processimport jsonimport timeimport osimport randomdef search():    time.sleep(random.randint(1, 3))   # 模拟网络延迟(查询环节)    with open("ticket.json", "r", encoding="utf-8")as f:        dic = json.load(f)        print(f"{os.getpid()}查看了票数, 剩余{dic['count']}")def paid():    with open("ticket.json", "r", encoding="utf-8")as f:        dic = json.load(f)        if dic["count"] > 0:            dic["count"] -= 1            time.sleep(random.randint(1, 3))            with open("ticket.json", "w",  encoding="utf-8")as f1:                json.dump(dic, f1)            print(f"{os.getpid()} 购买成功")def task():    search()    paid()    if __name__ == '__main__':    for i in range(6):        p = Process(target=task)        p.start()# 当多个进程共抢一个数据时, 如果要保证数据的安全, 必须要串行.# 要想让购买环节进行串行, 我们必须要加锁处理
from multiprocessing import Processfrom multiprocessing import Lockimport jsonimport timeimport osimport randomdef search():    time.sleep(random.randint(1, 3))    with open("ticket.json", encoding="utf-8")as f:        dic = json.load(f)        print(f"{os.getpid()} 查看了票数, 剩余{dic['count']}")def paid():    with open("ticket.json", encoding="utf-8")as f:        dic = json.load(f)    if dic["count"] > 0:        dic["count"] -= 1        time.sleep(random.randint(1, 3))        with open("ticket.json", "w", encoding="utf-8")as f1:            json.dump(dic, f1)        print(f"{os.getpid()}购买成功")def task(lock):    search()    lock.acquire()    paid()    lock.release()if __name__ == '__main__':    mutex = Lock()    for i in range(6):        p = Process(target=task, args=(mutex,))        p.start()"""203496 查看了票数, 剩余3203512 查看了票数, 剩余3203496购买成功203504 查看了票数, 剩余2203480 查看了票数, 剩余2203488 查看了票数, 剩余2203520 查看了票数, 剩余2203512购买成功203504购买成功"""# 当很多进程共抢一个资源(数据)时, 你要保证顺序(数据的安全), 一定要串行. # 互斥锁: 可以公平性的保证顺序以及数据的安全# 基于文件的进程之间的通信:        # 效率低        # 自己加锁麻烦而且很容易出现死锁

2.基于队列通信

1730033-20190821221713613-1550913961.png

3.基于管道通信

转载于:https://www.cnblogs.com/beichen123/p/11391594.html

你可能感兴趣的文章
明白这十个故事-->你也就参悟了人生 .
查看>>
linux忘记root密码后的解决办法
查看>>
killing rabbits
查看>>
Linux centos6.5 系统语言改成中文简体
查看>>
linux sort命令用法
查看>>
Linux入门第三天——more,less,head,tail,ls 用户权限
查看>>
回炉重造
查看>>
struts2-json-jquery ajax 操作
查看>>
不用改任何代码在Eclipse中使用AAR
查看>>
从cocos2dx中寻找函数指针传递的方法
查看>>
Unity目录结构
查看>>
欧拉回路和欧拉路径
查看>>
Java 推荐读物与源代码阅读
查看>>
BlogEngine.Net架构与源代码分析系列part1:开篇介绍
查看>>
N皇后问题
查看>>
优化深度神经网络(二)优化算法 SGD Momentum RMSprop Adam
查看>>
2016腾讯全球合作伙伴大会马化腾《给合作伙伴的一封信》
查看>>
Javascript学习笔记-基本概念-数据类型
查看>>
ES6总结
查看>>
c#隐藏tabcontrol选项卡
查看>>