【Python 多进程】
"
一、模块介绍
multiprocess模快
仔细说来,multiprocess不是一个模块,而是python中的一个操作、管理进程的包,之所以叫multi是取自multiple的多功能的意思,这个包中几乎包含了和进程有关的所有子模块。multiprocess.Process模块
Process能够帮助我们创建子进程,以及对子进程的一些控制.
- 参数:def __init__(self, group=None, target=None, name=None, args=(), kwargs={}):
group=None:该参数未使用,值始终为None
target:指定要调用的函数,即子进程要执行的任务
args:指定被调用对象的位置参数,以元组的形式传入,必须有逗号,如:args=('a',);此参数在源码中定义的只接收元组,但由于tuple数据类型底层原理的原因,此参数是可以传入一切可迭代对象,如:列表、字典、字符串、生成器表达式等
kwargs:指定被调用对象关键字参数,以字典的形式传入,关键字作为键,参数作为值
name:指定子进程的名称,默认名称为:Process-1、Process-2、...
- 方法
obj.start():启动子进程,并调用run()方法
obj.run():启动子进程时自动被调用,正是它去调用target参数指定的函数,自定义类中必须实现此方法
obj.terminate():强制终止子进程,不会进行任何清理操作,事实上是让操作系统去终止子进程;而操作系统终止进程是有一个过程的,所以子进程不会立即被终止;使用此方法需谨慎以下两种情况:1. 如果子进程中创建了子子进程,强制终止子进程后,子子进程将变成僵尸进程. 2. 如果子进程保存了一个锁,强制终止后,内存将不会被释放,进而导致死锁
obj.is_alive():判断子进程是否存活,若存活返回True,否则False
obj.join(timeout=None):阻塞父进程,等待子进程终止后再继续执行父进程,timeout指定等待超时时间;此方法只能用于使用start方法启动的子进程,对run方法启动的子进程无效
属性
obj.daemon:默认值为False,如果设为True,子进程将成为守护进程,此属性必须写在start()的前面;守护进程无法创建子进程,且会随着父进程的终止而终止
obj.name:返回子进程的名称
obj.pid:返回子进程的pid
obj.exitcode:子进程在运行时为None,如果为-N,则表示被信号N结束了
obj.authkey:子进程的身份验证键,默认由os.urandom()随机成生成的32bytes;是为涉及网络连接的底层进程间通讯提供安全性,这类连接只有在具有相同身份验证键时才能成功
二、使用Process创建进程
- windows系统使用Process模块需注意
由于windows操作系统中没有fork(Linux操作系统中创建进程的机制),因此启动子进程时采用的是导入启动子进程的文件的方式来完成进程间的数据共享。而导入文件即等于执行文件,因此如果将process()直接写在文件中将会无限递归子进程而报错,所以必须把创建子进程的部分使用if __name__ == '__main__':判断保护起来,以防止递归.
1. 基本操作
-
# 创建单个子进程及对子进程简单的控制
-
-
from multiprocessing import Process
-
from time import sleep
-
import os
-
-
-
def func(par):
-
print("%s, PID: %s" %(par, os.getpid()))
-
print("子进程终止后才继续执行父进程")
-
sleep(5)
-
-
-
if __name__ == '__main__':
-
-
p = Process(target=func, args=("子进程",)) # 实例化一个子进程对象p
-
# p.run() # run方法启动的子进程免疫join方法
-
p.start() # 子进程进入就绪状态,等待操作系统调度
-
-
print(p.is_alive()) # True: 子进程存活
-
p.join(1) # 阻塞父进程,等待子进程终止,等待超时时间1s
-
print(p.is_alive()) # False: 子进程终止
-
-
print("父进程, PID: %s" % os.getpid())
-
# 创建多个子进程
-
-
from multiprocessing import Process
-
from time import sleep
-
-
-
def func(n):
-
print("子进程", n)
-
sleep(0.1)
-
-
-
if __name__ == '__main__':
-
p_lst = []
-
for i in range(5): # 通过for循环启动多个子进程
-
p = Process(target=func, args=(i,))
-
p.start()
-
p_lst.append(p)
-
[p.join() for p in p_lst] # 阻塞父进程,等待所有子进程终止
-
-
print("父进程")
2. 自定义多进程类
-
# 自定义多进程类
-
-
from multiprocessing import Process
-
from time import sleep
-
-
-
class MyProcess(Process):
-
-
def __init__(self, target, name, sex):
-
self.sex = sex
-
super(MyProcess, self).__init__(target=target, name=name)
-
# self.name = name
-
# 父类Process初始化时会自动定义name属性,所以定义本类的name属性要写到super语句后面,
-
# 否则会被父类初始化时覆盖掉(MyProcess-子进程序号),或者给父类传参__init__(name=name)
-
-
def run(self): # 必写方法,用于调用函数
-
print("子进程:", self.name)
-
super(MyProcess, self).run()
-
-
-
func = lambda :print("执行了函数")
-
-
# 如果是Windows系统,此处要写一条__main__判断语句
-
p = MyProcess(func, 'zyk', 'boy')
-
p.start()
-
# p.run() # start方法会自动调用此方法
3.进程之间的数据共享与隔离
-
# 进程之间的数据共享与隔离
-
-
from multiprocessing import Process, Value
-
-
-
def func():
-
global n # !
-
n = 2 # 数据隔离:不会影响父进程中的变量n
-
print("子进程n: ", n) # 2
-
-
s.value = 4 # 数据共享:会影响父进程中的s
-
print("子进程s: ", s.value)
-
-
-
if __name__ == '__main__':
-
n = 1
-
s = Value('i', 3)
-
-
p = Process(target=func)
-
p.start()
-
p.join()
-
-
print("父进程n: ", n) # 1
-
print("父进程s: ", s.value) # 4
4.守护进程
-
# 守护进程
-
-
from multiprocessing import Process
-
from os import getpid
-
-
-
class MyProcess(Process):
-
-
def __init__(self, name):
-
super(MyProcess, self).__init__()
-
self.name = name
-
-
def run(self):
-
print(self.name, getpid())
-
# 父进程是先进入就绪状态的,所以父进程一般会先终止(除非父进程还有很长的逻辑要走)
-
# 子进程可能还未打印信息便随父进程终止而终止了,
-
-
p = MyProcess('zyk')
-
p.daemon = True # 确认为守护进程,随父进程终止而终止
-
p.start()
-
# p.join() # 阻塞父进程,方可正常执行完子进程,而显示打印信息
-
-
print("父进程")
5.进阶:socket消息加并发实例
-
# Server
-
-
from multiprocessing import Process
-
from socket import *
-
-
-
server = socket(AF_INET, SOCK_STREAM)
-
server.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
-
server.bind(('127.0.0.1', 8080))
-
server.listen(5)
-
-
-
def talk(conn, client_addr):
-
while True:
-
try:
-
msg = conn.recv(1472)
-
if not msg:break
-
conn.send(msg.upper())
-
except Exception:
-
break
-
-
-
if __name__ == '__main__':
-
while 1:
-
conn, client_addr = server.accept()
-
p = Process(target=talk, args=(conn, client_addr))
-
p.start()
-
print(p.name)
-
# Client
-
-
import socket
-
-
-
client = socket.socket()
-
client.connect_ex(('127.0.0.1', 8080))
-
-
-
while 1:
-
msg = input('>>>').strip()
-
if not msg:continue
-
-
client.send(msg.encode('utf-8'))
-
msg = client.recv(1472)
-
print(msg.decode('utf-8'))
完结
"
【Python 多进程】的更多相关文章
- Python多进程编程
转自:Python多进程编程 阅读目录 1. Process 2. Lock 3. Semaphore 4. Event 5. Queue 6. Pipe 7. Pool 序. multiproces ...
- Python多进程(1)——subprocess与Popen()
Python多进程方面涉及的模块主要包括: subprocess:可以在当前程序中执行其他程序或命令: mmap:提供一种基于内存的进程间通信机制: multiprocessing:提供支持多处理器技 ...
- Python多进程使用
[Python之旅]第六篇(六):Python多进程使用 香飘叶子 2016-05-10 10:57:50 浏览190 评论0 python 多进程 多进程通信 摘要: 关于进程与线程的对比, ...
- python多进程断点续传分片下载器
python多进程断点续传分片下载器 标签:python 下载器 多进程 因为爬虫要用到下载器,但是直接用urllib下载很慢,所以找了很久终于找到一个让我欣喜的下载器.他能够断点续传分片下载,极大提 ...
- Python多进程multiprocessing使用示例
mutilprocess简介 像线程一样管理进程,这个是mutilprocess的核心,他与threading很是相像,对多核CPU的利用率会比threading好的多. import multipr ...
- Python多进程并发(multiprocessing)用法实例详解
http://www.jb51.net/article/67116.htm 本文实例讲述了Python多进程并发(multiprocessing)用法.分享给大家供大家参考.具体分析如下: 由于Pyt ...
- python 多进程开发与多线程开发
转自: http://tchuairen.blog.51cto.com/3848118/1720965 博文作者参考的博文: 博文1 博文2 我们先来了解什么是进程? 程序并不能单独运行,只有将程 ...
- Python多进程----从入门到放弃
Python多进程 (所有只写如何起多进程跑数据,多进程数据汇总处理不提的都是耍流氓,恩,就这么任性) (1)进程间数据问题,因为多进程是完全copy出的子进程,具有独立的单元,数据存储就是问题了 ( ...
- day-4 python多进程编程知识点汇总
1. python多进程简介 由于Python设计的限制(我说的是咱们常用的CPython).最多只能用满1个CPU核心.Python提供了非常好用的多进程包multiprocessing,他提供了一 ...
- python 多进程 logging:ConcurrentLogHandler
python 多进程 logging:ConcurrentLogHandler python的logging模块RotatingFileHandler仅仅是线程安全的,如果多进程多线程使用,推荐 Co ...
随机推荐
- 利用Cadence PCB SI分析特性阻抗变化因素
1.概要 在进行PCB SI的设计时,理解特性阻抗是非常重要的.这次,我们对特性阻抗进行基础说明之外,还说明Allegro的阻抗计算原理以及各参数和阻抗的关系. 2.什么是特性阻抗? 2.1 传送线路 ...
- adb 连接手机
adb kill-server adb start-server 可能会遇到问题华为手机: 有应用遮挡了权限请求界面,设置应用无法验证你的回应 系统导航关闭悬浮球 然后重启adb server ad ...
- codeforces 1283F. DIY Garland(树+优先队列)
题目连接:https://codeforces.com/contest/1283/problem/F 题意:一根电线连接着两个点,这两个点分别代表着两个灯,灯有自己的编号i,其亮度是2 ^ i,每根电 ...
- mysql创建用户后无法访问数据库的问题
1.停止mysql服务器 sudo service mysql stop 2.启动mysql服务 sudo mysqld_safe --skip-grant-tables 3.登陆 mysql mys ...
- mybatis(六):设计模式 - 适配器模式
- WLC5520分布式端口(数据口)使用1G模块!
思科WLC5520有两个分布式端口. 在 10G 模式和 1G 模式之间切换•如果在端口 1 上未安装任何内容,则默认情况下主板配置为 10G 模式.因此,要切换到 1G 模式,则必须在端口 1上安 ...
- MySQL学习(七) 索引选择(半原创)
概述 该篇文章主要阐述一个例子(例子来自参考资料,侵删),然后总结今天相关的知识点. 例子 (例子来自参考文章,非原创) 创建表并插入数据,并执行查询 CREATE TABLE `t` ( `id` ...
- springboot06(静态资源映射)
xxxxAutoConfiguration xxxxproperties 对静态资源的映射规则 webjars @ConfigurationProperties(prefix = "spri ...
- C位域操作
位域的概念 1个字节包含8位,有些变量保存的数据不需要占用这么长的空间(比如bool类型,只有两个状态true和false, 1位就可以搞定,剩下的7位就浪费了),这就催生了“位域”结构,位域将1个字 ...
- rest framework 序列化之depth遇到用户表外键的尴尬情况
rest framework 序列化之depth遇到用户表外键的尴尬情况 问题:ModelSerializer序列化使用depth=1直接扩表把用户表所有信息查询出来的情况 class xxxSeri ...