vc sleep不占进程_Python 中的进程深入
封面图片来源:沙沙野
内容概览
- 进程的 join 方法
- 数据隔离
- 进程对象的其他方法
- 守护进程
- 抢票程序示例
- 队列
- 进程之间的通信 (IPC)
进程的 join 方法
- 假设要群发 1000 封邮件,发一封要 0.1s,那么发完也要 100s。如果不想这么久,就可以使用进程
from multiprocessing import Processdef send_mail(n):print("发送邮件%s" % n)if __name__ == "__main__":p = Process(target=send_mail, args=(1,))p.start()# 阻塞,直到子进程执行结束p.join() print("所有的邮件都发送完了")# 运行结果:
发送邮件1
所有的邮件都发送完了# 使用join()能够保证先打印 发送邮件,再打印 所有的邮件都发送完了
2. 同步发送邮件
from multiprocessing import Processdef send_mail(n):print("发送邮件%s" % n)if __name__ == "__main__":for i in range(10):p = Process(target=send_mail, args=(i,))p.start()p.join()print("所有的邮件都发送完了")# 运行结果:
发送邮件0
发送邮件1
发送邮件2
发送邮件3
发送邮件4
发送邮件5
发送邮件6
发送邮件7
发送邮件8
发送邮件9
所有的邮件都发送完了# 同步执行,意思就是上面的 0-9 的运行结果一定是按顺序的
3. 为了节省时间,应该让子进程运行的时候是异步的
from multiprocessing import Processdef send_mail(n):print("发送邮件%s" % n)if __name__ == "__main__":l = []for i in range(10):p = Process(target=send_mail, args=(i,))l.append(p)p.start()for p in l:p.join()print("所有的邮件都发送完了")# 运行结果:
发送邮件0
发送邮件1
发送邮件2
发送邮件4
发送邮件5
发送邮件6
发送邮件7
发送邮件3
发送邮件9
发送邮件8
所有的邮件都发送完了# 异步执行,说明多个进程在同一时刻进行
# 因此这里的 0-9 的结果不一定按顺序运行
from multiprocessing import Process
import timeprint("这是函数外部")def func():time.sleep(5)print("子进程开始运行")if __name__ == "__main__":p = Process(target=func)print("这是在子进程启动之前")p.start()print(p.is_alive())p.join()print(p.is_alive())print("主进程开始执行")# 运行结果:
这是函数外部
这是在子进程启动之前
True
子进程开始运行
False
主进程开始执行
数据隔离
n = 100
def func():global nn -= 1for i in range(100):func()
print(n)from multiprocessing import Process
n = 100
def func():global nn -= 1if __name__ == "__main__":p_list = []for i in range(100):p = Process(target=func)p.start()p_list.append(p)for p in p_list:p.join()print(n)# 运行结果:
0
100# 100 要等一会才会出结果,因为有join()
# 在进程之间数据是完全不能互通的
进程对象的其他方法
from multiprocessing import Process
import timeclass MyProcess(Process):# 给子进程传递参数def __init__(self, a, b): super().__init__()self.a = aself.b = bdef run(self):print("子进程开始执行")time.sleep(2)print("子进程结束", self.a, self.b)if __name__ == "__main__":p = MyProcess(1, 2)p.start()print(p.is_alive())time.sleep(1)print(p.name)p.terminate() # 非阻塞print(p.is_alive())time.sleep(0.5)print(p.is_alive())# 运行结果:
True
子进程开始执行
MyProcess-1
True
False
守护进程
- 一般用法:在开启子进程之前可以设置子进程为守护进程,p.daemon = True。守护进程随着主进程的代码执行结束而结束
import time
from multiprocessing import Processdef eye():while True:print("我是子进程, 告诉server端我很好")time.sleep(2)def main():print("我想做的事情")if __name__ == "__main__":p = Process(target=eye)p.start()main()# 运行结果:
我想做的事情
我是子进程, 告诉server端我很好
我是子进程, 告诉server端我很好
我是子进程, 告诉server端我很好
我是子进程, 告诉server端我很好
我是子进程, 告诉server端我很好
我是子进程, 告诉server端我很好
...# 因为设置了时间延迟,因此先执行主进程的 main()
# 另外,每隔 2s 执行子进程
2. 只要主进程的代码结束,子进程也会随之结束
import timefrom multiprocessing import Processdef eye():while True:print("我是守护进程, 每隔2s告诉server端我很好")time.sleep(2)def main():print("我是主进程, 5s后我将结束运行")time.sleep(5)print("主进程结束后,守护进程也不再执行")if __name__ == "__main__":p = Process(target=eye)p.daemon = True # p进程设置成 守护进程p.start()main()# 运行结果:
我是主进程, 5s后我将结束运行
我是守护进程, 每隔2s告诉server端我很好
我是守护进程, 每隔2s告诉server端我很好
我是守护进程, 每隔2s告诉server端我很好
主进程结束后,守护进程也不再执行
3. 守护进程只守护主进程,不会守护子进程
import time
from multiprocessing import Processdef eye():while True:print("我是守护进程, 我只守护主进程,每隔2s告诉server端我很好")time.sleep(2)def process2():print("我是子进程, 8s后我就结束运行,守护进程不会守护我")time.sleep(8)print("我是子进程, 我现在结束运行,主进程也跟着结束")def main():print("我是主进程,5s后我将结束运行")time.sleep(5)print("5s过去了,但是子进程还没结束,要等它结束我才能结束")if __name__ == "__main__":p = Process(target=eye)p2 = Process(target=process2)p.daemon = True # p进程设置成 守护进程p.start()p2.start()main()# 运行结果:
我是主进程,5s后我将结束运行
我是守护进程, 我只守护主进程,每隔2s告诉server端我很好
我是子进程, 8s后我就结束运行,守护进程不会守护我
我是守护进程, 我只守护主进程,每隔2s告诉server端我很好
我是守护进程, 我只守护主进程,每隔2s告诉server端我很好
5s过去了,但是子进程还没结束,要等它结束我才能结束
我是子进程, 我现在结束运行,主进程也跟着结束
4. 总结:守护进程会随着主进程代码的结束而结束,不会守护除了主进程代码之外的其他子进程
import time
from multiprocessing import Processdef eye():while True:print("我是守护进程, 我现在守护主进程和子进程,每隔2s告诉它们我很好")time.sleep(2)def process2():print("我是子进程,12s后我就结束运行")time.sleep(12)print("我是子进程,我现在结束运行")def main():print("我是主进程,5s后我就结束运行")time.sleep(5)print("我是主进程,我现在结束运行")if __name__ == "__main__":p = Process(target=eye)p2 = Process(target=process2)p.daemon = True # p进程设置成 守护进程p.start()p2.start()main()p2.join()# p2 结束之后这句代码才会结束
# 如果想让守护进程守护子进程,则像上面这样把子进程加个 join 就行# 运行结果:
我是主进程,5s后我就结束运行
我是守护进程, 我现在守护主进程和子进程,每隔2s告诉它们我很好
我是子进程,12s后我就结束运行
我是守护进程, 我现在守护主进程和子进程,每隔2s告诉它们我很好
我是守护进程, 我现在守护主进程和子进程,每隔2s告诉它们我很好
我是主进程,我现在结束运行
我是守护进程, 我现在守护主进程和子进程,每隔2s告诉它们我很好
我是守护进程, 我现在守护主进程和子进程,每隔2s告诉它们我很好
我是守护进程, 我现在守护主进程和子进程,每隔2s告诉它们我很好
我是守护进程, 我现在守护主进程和子进程,每隔2s告诉它们我很好
我是子进程,我现在结束运行
抢票程序:使用多进程实现 socket tcp 协议 server 端的并发
- server.py
import socket
from multiprocessing import Processdef func(conn):while 1:conn.send("我会一直向客户端发送这个信息".encode())if __name__ == "__main__":sk = socket.socket()sk.bind(("127.0.0.1", 8080))sk.listen()while 1:conn, addr = sk.accept()p = Process(target=func, args=(conn,))p.start()
2. 创建多个同样内容的 client.py
import socketsk = socket.socket()
sk.connect(("127.0.0.1", 8080))while True:msg = sk.recv(1024)print(msg.decode())# 运行结果都一样:
我会一直向客户端发送这个信息
我会一直向客户端发送这个信息
我会一直向客户端发送这个信息
...
3. 抢票示例
# 先查看余票,再抢票,注意是并发
# 先创建一个 ticket 的文件, 内容如下:
# {"count": 3}
# 3 表示还有 3 张票import json
import time
from multiprocessing import Process
from multiprocessing import Lockdef search(name):with open("ticket") as f:ticket_count = json.load(f)if ticket_count["count"] >= 1:print("%s号注意了: 有余票%s张" % (name, ticket_count["count"]))else:print("%s号注意: 没票了" % name)def buy(name):with open("ticket") as f:ticket_count = json.load(f)time.sleep(0.2)if ticket_count["count"] >= 1:print("有余票%s张" % ticket_count["count"])ticket_count["count"] -= 1print("%s号买到票了" % name)else:print("%s号没买到票" % name)with open("ticket", "w") as f:json.dump(ticket_count, f)def opt(lock, name):search(name)lock.acquire()buy(name)lock.release()if __name__ == "__main__":lock = Lock() # 锁,保证数据安全,不超票for i in range(10):p = Process(target=opt, args=(lock, "alex"+str(i),))p.start()# 运行结果:
alex0号注意了: 有余票3张
alex1号注意了: 有余票3张
alex2号注意了: 有余票3张
alex3号注意了: 有余票3张
alex4号注意了: 有余票3张
alex5号注意了: 有余票3张
alex6号注意了: 有余票3张
alex7号注意了: 有余票3张
alex8号注意了: 有余票3张
alex9号注意了: 有余票3张
有余票3张
alex0号买到票了
有余票2张
alex1号买到票了
有余票1张
alex2号买到票了
alex3号没买到票
alex4号没买到票
alex5号没买到票
alex6号没买到票
alex7号没买到票
alex8号没买到票
alex9号没买到票# 多个进程抢占同一个数据资源会造成数据不安全
# 必须要牺牲效率来保证数据的安全性
# 什么时候用到锁?
# 当多个进程使用同一份数据资源的时候/操作文件、操作共享数据、操作数据库等
队列:维护了一个秩序,先进先出,FIFO (first in first out)
import queueq = queue.Queue()
print(q) # <queue.Queue object at 0x0000029753908710>
q.put(1)
q.put(2)
q.put(3)
print(q) # <queue.Queue object at 0x0000029753908710>print(q.get()) # 1
print(q.get()) # 2
print(q.get()) # 3
进程之间的通信: IPC (Iter Process Communication)
from multiprocessing import Queue, Processdef son(q):msg1 = q.get()print(msg1)msg2 = q.get()print(msg2)msg3 = q.get()print(msg3)if __name__ == "__main__":q = Queue() # 队列是进程之间数据安全的数据类型,基于pickle + socket + Lockpro = Process(target=son, args=(q, ))pro.start()q.put("我是第一个被放进去的,取数据的时候我第一个出来")q.put("我是第二个被放进去的")q.put("我是最后被放进去的")# 运行结果:
我是第一个被放进去的,取数据的时候我第一个出来
我是第二个被放进去的
我是最后被放进去的# 还有一个管道Pipe,没有锁,数据不安全,这里暂不了解其用法
# 其实队列就是管道+锁的结合# 第三方工具(消息中间件):memocache, redis, kafka, rabbitmq
# 都是实现进程之间的通信的桥梁
# 队列的用法+模型
vc sleep不占进程_Python 中的进程深入相关推荐
- linux多进程server 进程池_Python 中的进程池与多进程
封面图片来源:沙沙野 内容概览 进程池 进程池和多进程的性能测试 进程池的其他机制 进程池的回调函数 进程池 如果有多少个任务,就开启多少个进程,实际上并不划算.由于计算机的 cpu 个数是非常有限的 ...
- python僵尸进程和孤儿进程_python中多进程应用及僵尸进程、孤儿进程
一.python如何使用多进程 创建子进程的方式 1.导入multiprocessing 中的Process类 实例化这个类 指定要执行的任务 target import os from multip ...
- python中线程和进程_python中线程和进程的简单了解
一.操作系统.应用程序 1.硬件:硬盘.cpu.主板.显卡........ 2.装系统(本身也是一个软件): 系统就是一个由程序员写出来的软件,该软件用于控制计算机得硬盘,让他们之间进行互相配合. 3 ...
- python协程怎么做数据同步_Python 中的进程、线程、协程、同步、异步、回调
进程和线程究竟是什么东西?传统网络服务模型是如何工作的?协程和线程的关系和区别有哪些?IO过程在什么时间发生? 一.上下文切换技术 简述 在进一步之前,让我们先回顾一下各种上下文切换技术. 不过首先说 ...
- python进程process类返回值_Python 中的进程
封面图片来源:沙沙野 内容概览进程必备的理论基础 进程的概念 并行和并发 进程的三状态 同步异步 进程模块 关于进程必备的理论基础操作系统的作用隐藏丑陋复杂的硬件接口,提供良好的抽象接口 管理.调度进 ...
- pythonmultiprocessing之 queue线程_python中的进程、线程(threading、multiprocessing、Queue、subprocess)...
Python中的进程与线程 学习知识,我们不但要知其然,还是知其所以然.你做到了你就比别人NB. 我们先了解一下什么是进程和线程. 进程与线程的历史 我们都知道计算机是由硬件和软件组成的.硬件中的CP ...
- python进程池和线程池_Python中的进程池与线程池(包含代码)
引入进程池与线程池 使用ProcessPoolExecutor进程池,使用ThreadPoolExecutor 使用shutdown 使用submit同步调用 使用submit异步调用 异步+回调函数 ...
- python创建新进程_Python并发编程(进程的创建)
动态性:进程的实质是程序在多道程序系统中的一次执行过程,进程是动态产生,动态消亡的. 并发性:任何进程都可以同其他进程一起并发执行 独立性:进程是一个能独立运行的基本单位,同时也是系统分配资源和调度的 ...
- python守护进程_Python实现守护进程
考虑如下场景:你编写了一个python服务程序,并且在命令行下启动,而你的命令行会话又被终端所控制,python服务成了终端程序的一个子进程.因此如果你关闭了终端,这个命令行程序也会随之关闭. 要使你 ...
最新文章
- 关于校验规则(Validation Rule)和业务规则(Bussiness Rule)的思考
- 记一次修复被篡改的IE首页
- 《图解CSS3:核心技术与案例实战》——1.1节什么是CSS3
- shell脚本输出菱形与等边三角形
- boost::all_clustering_coefficients用法的测试程序
- hadoop2.2单节点集群的搭建
- 用ghost备份和还原Linux系统
- MySQL服务器意外关机-无法启动多实例
- OpenGL ES和EGL关系(二十五)
- vue2.0中 怎么引用less?
- 洛谷 P1168 中位数 堆
- php libiconv close_无法编译PHP undefined reference to `libiconv_open
- win7触摸板怎么关闭_笔记本电脑触摸板快速关闭,避免误碰影响操作
- 佛理(引用别人的东西,怕忘记了不好找,拿来了,哈哈)
- directadmin php5.6,Directadmin 1.53开心版 安装教程
- 结构化设计(实验二)
- 深度学习笔记~集成方法bagging, boosting和stacking
- 【附源码】Python计算机毕业设计软件缺陷管理系统
- 台式计算机品牌及价格,全球十大台式电脑品牌 联想拥有良好的品质和适合的价格...
- java clip_java – 使用Clip对象播放多个声音片段
热门文章
- ubuntu 下 github 使用方法 以及异常修改
- ARM上的Bootloader的具体实现1071098736
- 4a安全管控 java cas_单点登录与权限管理本质:单点登录介绍
- mysql in 索引_关于MySQL种的in函数到底走不走索引、我和同事差点大打出手!
- c3p0 服务启动获取连接超时_c3p0获取连接Connection后的Close()---释疑
- Fiddler改包场景04——先拦截请求,修改请求,再拦截响应,修改响应,放行响应
- 黑马博客——详细步骤(二)项目功能的实现之登录功能
- 单元测试框架-Junit
- hive 时间函数_Hive常用大法(聚合/排序/分组)
- matlab自带SVM算法例子(附函数详解)