0510进程 multiprocess模块
process模块是一个创建进程的模块,借助这个模块,就可以完成进程的创建。
创建模块
import os
import time
from multiprocessing import Process def func(n,name,num = ):
print(os.getpid(),os.getppid())
time.sleep(1) if __name__ == '__main__':
print(os.getpid(),os.getppid()) # process id,parent process id
Process(target=func,args=[1,'alex',30]).start() # func
print('*'*20)
time.sleep(0.5)
print('*'*40)
# p = Process(target=func)
# p.start() # 主进程默认会等待子进程执行完毕之后才结束
# 主进程和子进程之间的代码是异步的
# 为什么主进程要等待子进程结束 回收一些子进程的资源
# 开启一个进程是有时间开销的 :操作系统响应开启进程指令,给这个进程分配必要的资源
强调:
1. 需要使用关键字的方式来指定参数
2. args指定的为传给target函数的位置参数,是一个元组形式,必须有逗号 参数介绍:
1 group参数未使用,值始终为None
2 target表示调用对象,即子进程要执行的任务
3 args表示调用对象的位置参数元组,args=(1,2,'egon',)
4 kwargs表示调用对象的字典,kwargs={'name':'egon','age':18}
5 name为子进程的名称 方法介绍:
1 p.start():启动进程,并调用该子进程中的p.run()
2 p.run():进程启动时运行的方法,正是它去调用target指定的函数,我们自定义类的类中一定要实现该方法
3 p.terminate():强制终止进程p,不会进行任何清理操作,如果p创建了子进程,该子进程就成了僵尸进程,使用该方法需要特别
小心这种情况。如果p还保存了一个锁那么也将不会被释放,进而导致死锁
4 p.is_alive():如果p仍然运行,返回True
5 p.join([timeout]):主线程等待p终止(强调:是主线程处于等的状态,而p是处于运行的状态)。timeout是可选的超时时
间,需要强调的是,p.join只能join住start开启的进程,而不能join住run开启的进程。 属性介绍:
1 p.daemon:默认值为False,如果设为True,代表p为后台运行的守护进程,当p的父进程终止时,p也随之终止,并且设定
为True后,p不能创建自己的新进程,必须在p.start()之前设置
2 p.name:进程的名称
3 p.pid:进程的pid
4 p.exitcode:进程在运行时为None、如果为–N,表示被信号N结束(了解即可)
5 p.authkey:进程的身份验证键,默认是由os.urandom()随机生成的32字符的字符串。这个键的用途是为涉及网络连接的底层
进程间通信提供安全性,这类连接只有在具有相同的身份验证键时才能成功(了解即可)
在Windows操作系统中由于没有fork(linux操作系统中创建进程的机制),在创建子进程的时候会自动 import 启动它的这个文件,
而在 import 的时候又执行了整个文件。因此如果将process()直接写在文件中就会无限递归创建子进程报错。所以必须把创建子
进程的部分使用if __name__ ==‘__main__’ 判断保护起来,import 的时候 ,就不会递归运行了。 同步控制
import os
from multiprocessing import Process
def func(exp):
print(os.getpid(),os.getppid())
result = eval(exp)
with open('file','w') as f:
f.write(str(result)) if __name__ == '__main__':
print(os.getpid(),os.getppid()) # process id,parent process id
# 3*5+5/6
p = Process(target=func,args=['3*5']) # func
p.start()
ret = 5/6
p.join() # join方法能够检测到p进程是否已经执行完了,阻塞直到p执行结束
with open('file') as f:
result = f.read()
ret = ret + int(result)
print(ret)
join :阻塞 直到 子进程结 开启多个进程
import os
import time
from multiprocessing import Process def process(n):
print(os.getpid(),os.getppid())
time.sleep(1)
print(n)
if __name__ == '__main__':
p_lst = []
for i in range(10):
p = Process(target=process,args=[i,])
p.start()
p_lst.append(p)
for p in p_lst:p.join() # 检测p是否结束 如果没有结束就阻塞直到结束 如果已经结束了就不阻塞
print('求和')
还有一种以继承Process类的形式开启进程的方式
import os
from multiprocessing import Process
class Myprocess(Process):
def __init__(self,*args):
super().__init__()
self.args = args
def run(self):
print(os.getpid(),self.name,self.pid)
for name in self.args:
print('%s和女主播聊天'%name) if __name__ == '__main__':
print(os.getpid())
p = Myprocess('yuan','wusir')
p.start() # 在执行start的时候,会帮我们主动执行run方法中的内容
进程中的数据隔离
from multiprocessing import Process
n = 100
def func():
global n
n += 1
print('son : ',n) #son : 101 if __name__ == '__main__':
p = Process(target=func)
p.start()
p.join()
print(n) #100
守护进程
import time
from multiprocessing import Process def func():
print('son start')
while True:
time.sleep(1)
print('son') def func2():
print('start :in func2')
time.sleep(5)
print('end : in func2')
if __name__ == '__main__':
p = Process(target=func)
# 在一个进程开启之前可以设置它为一个守护进程
p.daemon = True
p.start()
Process(target=func2).start()
time.sleep(2)
print('在主进程中')
分析:
主进程的代码 大概在2s多的时候就结束了
p2子进程实在5s多的时候结束
主进程结束
p是在什么时候结束的?
p是在主进程的代码执行完毕之后就结束了 主进程会等待子进程的结束而结束
守护进程的意义:
子进程会随着主进程代码的执行结束而结束
注意:守护进程不会关心主进程什么时候结束,我只关心主进程中的代码什么时候结束
守护进程的作用:
守护主进程,程序报活
主进程开启的时候 建立一个守护进程
守护进程只负责每隔1分钟 就给检测程序发一条消息
进程中的其他属性和方法
import time
from multiprocessing import Process def func():
print('wahaha')
time.sleep(20)
print('wahaha end')
if __name__ == '__main__':
p = Process(target=func)
p.start()
print(p.is_alive())
time.sleep(1)
p.terminate() # 在主进程中结束一个子进程
print(p.is_alive())
time.sleep(0.5)
print(p.is_alive())
print(p.pid) #相当于self.pid 查看进程ID
print(p.name) #相当于self.name 查看进程名
使用多进程实现socket聊天并发-server
server端
import socket
from multiprocessing import Process
def func(conn):
while True:
msg = conn.recv(1024).decode('utf-8')
print(msg)
conn.send('sb'.encode('utf-8'))
conn.close() if __name__ == "__main__":
sk = socket.socket()
sk.bind(('127.0.0.1', 9000))
sk.listen()
while True:
conn, addr = sk.accept()
Process(target=func,args=[conn,]).start()
sk.close() client端
import socket sk = socket.socket()
sk.connect(('127.0.0.1',9000))
while True:
inp = input('>>>').encode('utf-8')
sk.send(inp)
msg = sk.recv(1024).decode('utf-8')
print(msg)
sk.close()
锁
import os
import time
import random
from multiprocessing import Process
from multiprocessing import Lock
def work(n,lock):
lock.acquire()
print('%s: %s in running'%(n,os.getpid()))
time.sleep(random.random())
print('%s:%s in done'%(n,os.getpid()))
lock.release() if __name__ =='__main__': lock = Lock()
for i in range(10):
p = Process(target=work, args=(i,lock))
p.start() 抢票系统
import json
import time
import random
from multiprocessing import Process,Lock
def chenck(i):
with open('file')as f:
count = json.load(f)
print('percon%s,剩余%s张票'%(i,count['count']))
time.sleep(random.random()) def buy(i,lock):
chenck(i)
lock.acquire()
with open('file')as f:
count = json.load(f)
time.sleep(random.random())#模拟读数据的网络延迟
if count['count'] > 0:
print('%s抢票成功'%i)
else:
print('%s抢票失败'%i)
time.sleep(random.random())#模拟读数据的网络延迟 with open('file','w')as f:
count['count'] -= 1
json.dump(count,f)
lock.release() if __name__ == '__main__':
lock = Lock()
for i in range(10): #模拟并发10个客户端抢票
Process(target=buy, args=[i, lock]).start()
上面这种情况虽然使用加锁的形式实现了顺序的执行,但是程序又重新变成串行了,这样确实会浪费了时间,却保证了数据的安全。
加锁可以保证多个进程修改同一块数据时,同一时间只能有一个任务可以进行修改,即串行的修改,没错,速度是慢了,但牺牲了速
度却保证了数据安全。
虽然可以用文件共享数据实现进程间通信,但问题是:
1.效率低(共享数据基于文件,而文件是硬盘上的数据)
2.需要自己加锁处理
信号量
KTV 4个房子
import time
import random
from multiprocessing import Process,Semaphore
def ktv(i,sem):
sem.acquire()
print('person %s 进来唱歌了'%i)
time.sleep(random.randint(1,5))
print('person %s 从ktv出去了'%i)
sem.release() if __name__ == '__main__':
sem = Semaphore(4)
for i in range(10):
Process(target=ktv,args=(i,sem)).start() 锁+计数器
.acquire() 计数器-1
计数器减为0 = 阻塞
.release() 计数器+1
事件--------------红绿灯
multiprocess.Event(了解)
状态
# 子进程 如何 受到状态的影响?
# wait() 的方法 等待 ---> 信号
# 发送信号:通过事件来发送信号
# True set 把信号设置为True
# False clear 把信号设置位False # 红绿灯 :
# 车 进程 wait() 等红灯
# 根据状态变化 wait遇到True信号,就非阻塞
# 遇到False信号,就阻塞
# 交通灯 进程 红灯 --> False
# 绿灯 --> True # 事件
# wait的方法 根据一个状态来决定自己是否要阻塞
# 状态相关的方法
# set 将状态改为T
# clear 将状态改为F
# is_set 判断当前的状态是否为T # from multiprocessing import Event # # 创建一个事件的对象
# e = Event()
# print(e.is_set()) # 在事件的创世之初,状态为False
# e.set()
# e.wait()
# print(e.is_set())
# e.clear()
# print(e.is_set())
# e.wait() import time
import random
from multiprocessing import Process,Event def car(i,e): # 感知状态的变化
if not e.is_set(): # 当前这个事件的状态如果是False
print('car%s正在等待'%i) # 这辆车正在等待通过路口
e.wait() # 阻塞 直到有一个e.set行为 # 等红灯
print('car%s通过路口'%i) def traffic_light(e): # 修改事件的状态
print('\033[1;31m红灯亮\033[0m')
# 事件在创立之初的状态是False,相当于我程序中的红灯
time.sleep(2) # 红灯亮2s
while True:
if not e.is_set(): # False
print('\033[1;32m绿灯亮\033[0m')
e.set()
elif e.is_set():
print('\033[1;31m红灯亮\033[0m')
e.clear()
time.sleep(2) if __name__ == '__main__':
e = Event()
Process(target=traffic_light,args=[e,]).start()
for i in range(50):
time.sleep(random.randrange(0,5,2))
Process(target=car,args=[i,e]).start()
进程间通信——队列和管道(multiprocess.Queue、multiprocess.Pipe)
0510进程 multiprocess模块的更多相关文章
- 进程的概念及multiprocess模块的使用
一.进程 进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础.在早期面向进程设计的计算机结构中,进程是程序的基本执行实体:在 ...
- Python multiprocess模块(上)
multiprocess模块 一. Process模块介绍 1. 直接使用Process模块创建进程 (1)主进程和子进程 (2)if __name__ == "__main__" ...
- Python之路(第三十七篇)并发编程:进程、multiprocess模块、创建进程方式、join()、守护进程
一.在python程序中的进程操作 之前已经了解了很多进程相关的理论知识,了解进程是什么应该不再困难了,运行中的程序就是一个进程.所有的进程都是通过它的父进程来创建的.因此,运行起来的python程序 ...
- {Python之进程} 背景知识 什么是进程 进程调度 并发与并行 同步\异步\阻塞\非阻塞 进程的创建与结束 multiprocess模块 进程池和mutiprocess.Poll
Python之进程 进程 本节目录 一 背景知识 二 什么是进程 三 进程调度 四 并发与并行 五 同步\异步\阻塞\非阻塞 六 进程的创建与结束 七 multiprocess模块 八 进程池和mut ...
- 网络基础之 并发编程之进程,多路复用,multiprocess模块
并发 1. 背景知识 2. 什么是进程 3. 进程调度 4. 并发与并行 5 同步\异步\阻塞\非阻塞(重点) 6.multiprocess模块 7.僵尸进程与孤儿进程 1.背景知识 一操作系统的作用 ...
- multiprocess模块---进程---进程队列
首先明白几个概念: 同步:做完一件事情,再做另外一件事情 异步:做一件事情的时候,可以再做另外一件事情 阻塞:recv sleep accept input recvfrom 非阻塞:没有遇见上面这 ...
- Python开发——14.threading模块和multiprocess模块
一.threading模块 1.threading类的两种创建方法 (1)直接创建 import time import threading def Hi(num): print("hell ...
- multiprocess模块
什么是进程 什么是进程 进程是计算机中的程序关于某数据集合一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础,进程与进程之间数据隔离,执行过程异步 为什么会出现进程的概念 合理利用 ...
- 36_并发编程-multiprocess模块
仔细说来,multiprocess不是一个模块而是python中一个操作.管理进程的包. 之所以叫multi是取自multiple的多功能的意思,在这个包中几乎包含了和进程有关的所有子模块.由于提供的 ...
随机推荐
- discuz x 系列目录结构说明
api ┄┄┄外部接口 connect ┄┄┄腾讯互联 db ┄┄┄UCenter数据库备份接口 google ┄┄┄Google引擎使用 javascript ┄┄┄数据和广告的 J ...
- Cognos入门教程
Cognos入门教程 1. ReportStudio入门教程 ReportStudio入门教程(http://blog.csdn.net/column/details/ygy-reportstudio ...
- ASP.NET 4.0尚未在Web服务器注册 解决
http://www.cnblogs.com/lvxiouzi/p/3511446.html 安装asp.net 4.0.30319.0版本 命令: %windir%\Microsoft.NET\Fr ...
- 银联支付-产品测试sdk使用流程
准备工作: 到https://open.unionpay.com/ajweb/help/file/techFile?productId=66下载开发文档和sdk 下载之后进行解压将Java Versi ...
- LeetCode - Delete Duplicate Emails
Discription:Write a SQL query to delete all duplicate email entries in a table named Person, keeping ...
- WEB安全第四篇--与数据库的亲密接触:SQL注入攻击
零.前言 最近做专心web安全有一段时间了,但是目测后面的活会有些复杂,涉及到更多的中间件.底层安全.漏洞研究与安全建设等越来越复杂的东东,所以在这里想写一个系列关于web安全基础以及一些讨巧的pay ...
- 【BZOJ3932】[CQOI2015]任务查询系统 主席树
[BZOJ3932][CQOI2015]任务查询系统 Description 最近实验室正在为其管理的超级计算机编制一套任务管理系统,而你被安排完成其中的查询部分.超级计算机中的 任务用三元组(Si, ...
- netty的解码器与粘包和拆包
tcp是一个“流”的协议,一个完整的包可能会被TCP拆分成多个包进行发送,也可能把小的封装成一个大的数据包发送,这就是所谓的TCP粘包和拆包问题. 假设客户端分别发送数据包D1和D2给服务端,由于服务 ...
- AVG
AVG([ DISTINCT | ALL ] expr) [ OVER(analytic_clause) ] SELECT MANAGER_ID, LAST_NAME, ...
- 学习认识Spring原理
学习认识Spring原理 Spring 是一种业务层框架.搭建Spring框架需要Spring开发包和commons-logging包.Spring的核心思想是控制反转也称依赖注入(创建者--(实例) ...