多进程笔记:

在Python中多进程的创建方式对比:

1.在Python中,可以通过os.fork()创建子进程,但是这种方式智能在'linux'和'unix'以及'mac'下面使用,不能跨平台,所以一般不推荐使用这种方式。

2.使用'multiprocessing'模块也可以创建多进程,并且这种方式在写起来更加简单,并且支持跨平台,

所以一般推荐使用'multiprocessing'的方式来写多进程的代码。

'multiprocessing'的基本用法:

'multiprocessing'这个模块下面有一个'Process'的类,使用这个类可以创建一个多进程,使用方式如下:

from multiprocessing import Process
import os def demo():
print('我是子进程--->')
print('子进程进程号是%s'%(os.getpid()))
print('父进程进程号是%s'%(os.getppid())) if __name__ == '__main__':
p = Process(target=demo)
p.start()
print('主进程的进程号是%s'%(os.getpid()))

需要注意一点的是,如果在'windows'操作系统下,

所有和进程创建相关的代码都必须放在'if name == 'main''下面,否则会报错。

获取进程号:

1.通过'os.getpid()'可以获取到当前这个进程的id

2.通过'os.getppid()'可以获取到当前这个进程的父进程的id

父进程会等待所有子进程执行完毕后再退出:

如果在父进程中执行完所有代码后,还有子进程在执行,那么父进程会等待子进程执行完所有代码后再退出。

'join'方法:

'join'方法可以让你的主进程阻塞,直到这个子进程执行完毕以后才会执行主进程后面的代码。

from multiprocessing import Process
import os
import time def demo():
for i in range(5):
print('子进程')
time.sleep(1) if __name__ == '__main__':
p = Process(target=demo)
p.start()
print('主进程') p.join() # join方法的时候,就相当于主进程会阻塞在这个地方,直到这个子进程执行完毕以后才会执行父进程后的代码
print('执行完毕')

适用于类的方式创建子进程

1.使用'Process'作为父类,重新自定义一个类。

2.在自定义的类中,重写父类的'run'方法,这个是必须的,其他方法,就按照你平时如何写就可以了。

3.使用自定义的进程类创建子进程的时候,不需要传'target'参数。

from multiprocessing import Process
import os
class MyProcess(Process):
def run(self):
print('子进程的id:%s' % os.getpid())
print('父进程的id:%s' % os.getppid())
for i in range(5):
print('子进程:%s'%i) if __name__ == '__main__':
p = MyProcess()
p.start()
print('父进程的id:%s'%os.getpid())
print('子进程开始了')
p.join()
print('子进程结束了')

进程池:

1.'multiprocessing'中的'Pool'可以实现一个容器,来管理子进程。

2.使用进程池有什么好处,进程池可以控制同一时刻,最多只能有多少个进程在运行。

3.主进程不会等待进程池中的子进程都执行完毕以后再退出,二十如果父进程代码执行完毕以后,就会将整个程序都退出,

所有我们在写进程池的时候,应该使用'pool.join()'来保证进程池中所有的子进程都能够执行完成。

4.'apply_async'相当于是并联的方式执行(同一时刻只能执行一个任务,并且只能等待前面的任务执行完后,才能执行后面的任务)

from multiprocessing import Pool
import os
import time
def demo(num):
for x in range(5):
print('子进程id:%s ,值:%s'% (os.getpid(),num))
time.sleep(2)
if __name__ == '__main__':
# 这个池子中同一时刻最多只能有3个进程
pool = Pool(2)
for x in range(10):
pool.apply_async(demo,args=(x,))
# 关闭进程池,不能再添加新进程了
pool.close()
# 主进程把子进程添加到进程池中后,不会等待进程池中其他的子进程都执行完毕后再退出,
# 而是当主进程的代码执行完毕后悔立刻退出,因此如果这个地方没有join,那么子进程将得不到执行。
pool.join()

进程间数据不共享:

在程序中创建了子进程,子进程会完全copy一份主进程的环境,包括变量、函数、类等。

所以在子进程中使用变量、函数等的时候,其实是使用的是子进程中的那一份,跟主进程没有任何关系。

from  multiprocessing import Process

AGE = 1

def hello():
print('hello') def greet(names):
global AGE
AGE += 1
names.append('ketang')
print('=====子进程代码=====')
print('AGE的值:%d, AGE的id:%s' % (AGE,id(AGE)))
print('names:%s' % names)
print(id(hello))
print('=====子进程代码=====') if __name__ == '__main__':
names = ['demo']
p = Process(target=greet,args=(names,))
p.start()
p.join()
print('=====父进程代码=====')
print('AGE的值:%d, AGE的id:%s' % (AGE,id(AGE)))
print('names:%s' % names)
print(id(hello))
print('=====父进程代码=====')

Queue消息队列:

  1. Queue(n):初始化一个消息队列,并指定这个队列中最多能够容纳多少条消息。
  2. put(obj,[block,[timeout]]):推入一条消息到这个队列中。默认是阻塞的,也就是说如果这个消息队列中已经满了,

    那么会一直等待,将这个消息添加到消息队列中。timeout可以指定这个阻塞最长时间,如果超过这个时间还是满的,就会抛出异常。
  3. put_nowait():非阻塞的推入一条消息,如果这个队列已经满了,那么会立马抛出异常。
  4. qsize():获取这个消息队列消息的数量。
  5. full():判断这个消息队列是否满了。
  6. empty():判断这个消息队列是否空了。
  7. get([block,[timeout]]):获取队列中的一条消息,然后将其从队列中移除,block默认为True。如果设置block为False,

    那么如果没值,会立马抛出异常。timeout指定如果多久没有获取到值后会抛出异常。
from multiprocessing import Queue

# Queue可以指定maxsize的值
# 以后这个队列中就只能装maxsize个值
# 如果不指定,那么就是为-1
# -1 意味着可以装任意多个消息,直到你的内存满了
q = Queue(3) # put方法,可以传递任意数据类型的消息
q.put('m1')
q.put('m2')
q.put('m3')
# qsize: 获取这个消息队列中总共的消息数量
print('qsize:%s' % q.qsize())
# full, 如果消息队列满了,那么会返回True,否则返回False
print(q.full())
# empty:如果消息队列为空,那么会返回True,否则返回False
print(q.empty()) # put方法默认是阻塞的方式
# 如果消息队列已经满了,那么会阻塞在这个地方,直到这个消息队列没有满为止
# block参数:可以设置为False,如果为False,那么意味着不会阻塞,如果消息队列满了,那么会立马抛出一个异常
# timeout参数:指定阻塞的最长时间。如果超过了这个时间就不再阻塞,而是抛出一个异常。
# q.put('m4',block=True,timeout=2)
# put_nowait:其实等价于q.put(obj,block=False)
# q.put_nowait('m4')
# print('finished') # get方法:获取到的是第一个添加进去的值。
# get方法:除了获取这个值外,还会把这个值从消息队列中删除掉
# block参数:默认是等于True,即以阻塞的方式获取值,如果这个队列中没有任何消息,那么会阻塞到这个地方。如果block=False,那么如果队列中没有值,就会立即抛出异常。
# timeout参数:指定阻塞的最长时间,如果超过了这个时间就不再阻塞,而是抛出一个异常
print(q.get())
print(q.get())
print(q.get())
print(q.get(block=True,timeout=2))

使用Queue做进程间通信:

  1. Process进程做通信:直接使用Queue的对象座位进程的参数就可以了。
  2. Pool进程做通信,应该使用multiprocessing.Manager().Queue()对象来做通信,

    这个对象的使用方法跟multiprocessing.Queue()是一样的。
from multiprocessing import Process,Queue
import os def write(q):
for x in ['m1','m2','m3']:
q.put(x)
print('子进程%s已经存放了消息:%s' % (os.getpid(),x)) def read(q):
while True:
try:
msg = q.get(block=False)
print('子进程%s已经读取了消息:%s' % (os.getpid(),msg))
except:
print('所有消息都已经取出来了')
break if __name__ == '__main__':
q = Queue()
pw = Process(target=write,args=(q,))
pr = Process(target=read,args=(q,)) pw.start()
pr.start() pw.join()
from multiprocessing import Process,Queue,Pool,Manager
import os def write(q):
for x in ['m1','m2','m3']:
q.put(x)
print('子进程%s已经存放了消息:%s' % (os.getpid(),x)) def read(q):
while True:
try:
msg = q.get(block=False)
print('子进程%s已经读取了消息:%s' % (os.getpid(),msg))
except:
print('所有消息都已经取出来了')
break if __name__ == '__main__':
q = Manager().Queue()
pool = Pool(2)
pool.apply(func=write,args=(q,))
pool.apply(func=read,args=(q,))

python-----多进程笔记的更多相关文章

  1. python学习笔记——multiprocessing 多进程组件-队列Queue

    1 消息队列 1.1 基本语法 消息队列:multiprocessing.Queue,Queue是对进程安全的队列,可以使用Queue实现对进程之间的数据传输:还有一个重要作用是作为缓存使用. Que ...

  2. python学习笔记——multiprocessing 多进程组件 Pipe管道

    进程间通信(IPC InterProcess Communication)是值在不同进程间传播或交换信息. IPC通过有管道(无名管道 和 有名 / 命名管道).消息队列.共享存储 / 内容.信号量. ...

  3. python学习笔记——multiprocessing 多进程组件 进程池Pool

    1 进程池Pool基本概述 在使用Python进行系统管理时,特别是同时操作多个文件目录或者远程控制多台主机,并行操作可以节约大量时间,如果操作的对象数目不大时,还可以直接适用Process类动态生成 ...

  4. python学习笔记——multiprocessing 多进程模块Process

    系统自带的fork模块创建的多进程是基于Linux或Unix平台的,而window平台并不支持: python中的multiprocess为跨平台版本的多进程模块,支持子进程.通信和共享数据.执行不同 ...

  5. python学习笔记——fork()创建多进程

    1 进程概述 引自 Python 多进程 fork()详解 1.1 进程 进程是程序的一次动态执行过程,它对应了从代码加载.执行到执行完毕的一个完整过程. 进程是系统进行资源分配和调度的一个独立单位. ...

  6. Python学习笔记进阶篇——总览

    Python学习笔记——进阶篇[第八周]———进程.线程.协程篇(Socket编程进阶&多线程.多进程) Python学习笔记——进阶篇[第八周]———进程.线程.协程篇(异常处理) Pyth ...

  7. Web Scraping with Python读书笔记及思考

    Web Scraping with Python读书笔记 标签(空格分隔): web scraping ,python 做数据抓取一定一定要明确:抓取\解析数据不是目的,目的是对数据的利用 一般的数据 ...

  8. python学习笔记整理——字典

    python学习笔记整理 数据结构--字典 无序的 {键:值} 对集合 用于查询的方法 len(d) Return the number of items in the dictionary d. 返 ...

  9. Python多进程编程

    转自:Python多进程编程 阅读目录 1. Process 2. Lock 3. Semaphore 4. Event 5. Queue 6. Pipe 7. Pool 序. multiproces ...

  10. VS2013中Python学习笔记[Django Web的第一个网页]

    前言 前面我简单介绍了Python的Hello World.看到有人问我搞搞Python的Web,一时兴起,就来试试看. 第一篇 VS2013中Python学习笔记[环境搭建] 简单介绍Python环 ...

随机推荐

  1. 35个高级Python知识点总结

    原文地址:https://blog.51cto.com/xvjunjie/2156525 No.1 一切皆对象 众所周知,Java中强调“一切皆对象”,但是Python中的面向对象比Java更加彻底, ...

  2. 最新 盛天网络java校招面经 (含整理过的面试题大全)

    从6月到10月,经过4个月努力和坚持,自己有幸拿到了网易雷火.京东.去哪儿.盛天网络等10家互联网公司的校招Offer,因为某些自身原因最终选择了盛天网络.6.7月主要是做系统复习.项目复盘.Leet ...

  3. luoguP1058:立体图 (真的不是娱乐向_(:з」∠)_)

    题目描述 小渊是个聪明的孩子,他经常会给周围的小朋友们将写自己认为有趣的内容.最近,他准备给小朋友们讲解立体图,请你帮他画出立体图. 小渊有一块面积为m*n的矩形区域,上面有m*n个边长为1的格子,每 ...

  4. springboot与shiro在html中使用shiro标签

    上一章讲环境搭建 springboot与shiro和mybatis和mysql 现在讲html中怎么使用shiro标签,这里是基于上一章讲的 在pom文件引入依赖 <dependency> ...

  5. 【LOJ】#2210. 「HNOI2014」江南乐

    LOJ#2210. 「HNOI2014」江南乐 感觉是要推sg函数 发现\(\lfloor \frac{N}{i}\rfloor\)只有\(O(\sqrt{N})\)种取值 考虑把这些取值都拿出来,能 ...

  6. Redis 常用命令学四:集合类型命令

    1.增加和删除命令 127.0.0.1:6379> SADD st a (integer) 1 127.0.0.1:6379> SADD st r f g (integer) 3 127. ...

  7. java源码 -- TreeSet

    这个TreeSet其实和HashSet类似.HashSet底层是通过HashMap实现的,TreeSet其实底层也是通过TreeMap实现的. 简介 TreeSet的作用是保存无重复的数据,不过还对这 ...

  8. VC++实现遍历指定文件夹

    VC++实现遍历指定文件夹,并进行深度遍历,一级,二级...最终列出该文件夹下所有文件全路径. #include "stdafx.h" #include <iostream& ...

  9. vue.js中 ,回车键实现登录或者提交表单!

    vue的功能非常强大,但是我们作为一个后端开发人员,前端的东西不一定都弄的很明白,今天就给大家介绍一个回车提交表单的真实案例,达到回车登录的效果! @ keyup.enter 实现的效果 <in ...

  10. Apache Tomcat 安装与配置教程

    JDK的安装与配置 1. 从官网下载JDK https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-213315 ...