多进程 multiprocessing模块

multiprocessing模块提供了一个Process类来代表一个进程对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#!/usr/bin/env python3
# coding:utf-8
'''
Created on: 2016年3月5日
 
@author: 张晓宇
 
Email: 61411916@qq.com
 
Version: 1.0
 
Description: 多进程演示程序
 
Help:
'''
from multiprocessing import Process
import os
 
 
def run_proc(name):
    # 子进程要执行的函数
    print('Run child process %s (%s)...' % (name, os.getpid())) # os.getpid()表示获得当前进程的pid
 
if __name__=='__main__':
    print('Parent process %s.' % os.getpid()) # 打印父进程的pid
    p = Process(target=run_proc, args=('test',)) # 创建进程对象,参数结构和多线程一样
    print('Child process will start.')
    p.start() # 启动子进程
    p.join() # 阻塞等待子进程执行完毕
    print('Child process end.')

进程间通信

Queue

不同进程间内存是不共享,所以多进程不能像多线程一样通过全局变量(当然全局变量也是不提倡的),所以只能通过队列,多进程模块也自带一个队列Queue,使用方法和threading里的queue差不多

Pipe

管道,可以理解为两个进程之间的一个桥梁

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#!/usr/bin/env python3
# coding:utf-8
'''
Created on: 2016年3月5日
 
@author: 张晓宇
 
Email: 61411916@qq.com
 
Version: 1.0
 
Description: 管道演示程序
 
Help:
'''
from multiprocessing import Process, Pipe
 
def f(conn):
    conn.send([42, None, 'hello']) # 网管道里传递数据
    conn.close()
 
if __name__ == '__main__':
    parent_conn, child_conn = Pipe() # 一个是父进程的管道对象,一个是子进程的对象,自己成往里面send,父进程对象recv,有点像socket
    p = Process(target=f, args=(child_conn,)) # 把管道对象作为参数传递给子进程
    p.start()
    print(parent_conn.recv())   # 接收管道里的数据并打印出来
    p.join()

执行结果

1
[42, None, 'hello']

有人会说既然可以往子进程要执行的而函数传递参数,直接通过这个参数取子进程传递过来的数据就好了,比如可以用列表等可变数据类型(字符串和数值型等不可变类型的数据,想都不要想,统一进程都做不到)为啥还用管道或队列

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#!/usr/bin/env python3
# coding:utf-8
'''
Created on: 2016年3月5日
 
@author: 张晓宇
 
Email: 61411916@qq.com
 
Version: 1.0
 
Description: 管道演示程序
 
Help:
'''
from multiprocessing import Process, Pipe
 
def f(conn, strinfo):
    conn.send([42, None, 'hello']) # 网管道里传递数据
    conn.close() # 关闭管道
    strinfo.append('child')
 
if __name__ == '__main__':
    parent_conn, child_conn = Pipe() # 一个是父进程的管道对象,一个是子进程的对象,自己成往里面send,父进程对象recv,有点像socket
    strinfo = ['parent']
    p = Process(target=f, args=(child_conn, strinfo)) # 把管道对象作为参数传递给子进程
    p.start()
    print(parent_conn.recv())   # 接收管道里的数据并打印出来
    print(strinfo)
    p.join()

执行结果

1
2
[42, None, 'hello']
['parent']

从执行结果中可以看出来,strinfo的值并没有变化,那是因为,进程启动的时候重新划分了内存空间,等于将strinfo在子进程中copy了一份,已经和父进程中的strinfo没有半毛钱关系了所以要有管道队列等

进程池

进程池内部维护一个进程序列,当使用时,则去进程池中获取一个进程, 如果进程池序列没有可提供的进程,那么就会等待,知道有可用进程为止

Pool模块有两种常用的启动进程的方法

apply和apply_assync,从字面上理解是apply_assync是异步的,其实就是apply_assync支持把一个函数作为参数传递进去,当进程函数执行完的时候可以通过return一个值,这个值,会自动作为参数传递个传递进来的函数,并执行该函数,我们称之为回调(callback)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#!/usr/bin/env python
# coding:utf-8
'''
Created on: 2016年3月5日
 
@author: 张晓宇
 
Email: 61411916@qq.com
 
Version: 1.0
 
Description: 进程池演示程序
 
Help:
'''
from  multiprocessing import Pool, freeze_support
import time
 
def Foo(i):
    '''
    子进程执行的函数
    :param i:
    :return:
    '''
    time.sleep(2)
    return i+100
 
def Bar(arg):
    '''
    子进程回调函数
    :param arg:
    :return:
    '''
    print('-->exec done:',arg)
 
if __name__ == '__main__': # 这个在windows环境中绝对不能省略否则会报错
    freeze_support()
    pool = Pool(5) # 创建进程池对象
 
    for i in range(10):
        pool.apply_async(func=Foo, args=(i,), callback=Bar)
        # pool.apply(func=Foo, args=(i,))
    print('end')
    pool.close()
    pool.join()#进程池中进程执行完毕后再关闭,如果注释,那么程序直接关闭。

执行结果

1
2
3
4
5
6
7
8
9
10
11
end
-->exec done: 100
-->exec done: 101
-->exec done: 102
-->exec done: 103
-->exec done: 104
-->exec done: 105
-->exec done: 106
-->exec done: 107
-->exec done: 108
-->exec done: 109

我的Python成长之路---第八天---Python基础(25)---2016年3月5日(晴)的更多相关文章

  1. 我的Python成长之路---第八天---Python基础(24)---2016年3月5日(晴)

    多线程编程 什么是多线程,线程是操作系统能够进行运算调度的最小单位.他包含在进程之中,是进程中的实际运作单位.线程是进程中一个单顺序的空值六,一个进程可以并发多个线程,每个线程可以并行处理不同的任务. ...

  2. 我的Python成长之路---第八天---Python基础(23)---2016年3月5日(晴)

    socketserver 之前讲道德socket模块是单进程的,只能接受一个客户端的连接和请求,只有当该客户端断开的之后才能再接受来自其他客户端的连接和请求.当然我们也可以通过python的多线程等模 ...

  3. 我的Python成长之路---第一天---Python基础(1)---2015年12月26日(雾霾)

    2015年12月26日是个特别的日子,我的Python成之路迈出第一步.见到了心目中的Python大神(Alex),也认识到了新的志向相投的伙伴,非常开心. 尽管之前看过一些Python的视频.书,算 ...

  4. 我的Python成长之路---第二天---Python基础(7)---2016年1月9日(晴)

    再说字符串 一.字符串的编码 字符串的编码是个很令人头疼的问题,由于计算机是美国人发明的,他们很理所当然的认为计算机只要能处理127个字母和一些符号就够用了,所以规定了一个字符占用8个比特(bit)也 ...

  5. python成长之路——第八天

    pickle,load :切记:如果load的是个对象的话,必须导入构建这个对象的类     封装 类和对象的关系: 每个对象里都有一个类对象指针,指向类     继承:支持单继承和多继承 print ...

  6. 我的Python成长之路---第一天---Python基础(6)---2015年12月26日(雾霾)

    七.列表——list Python的列表是一种内置的数据类型,是由Python的基本数据类型组成的有序的集合.有点类似C语言的数组,但与数组不同的是,Python在定义列表的时候不用指定列表的容积(长 ...

  7. 我的Python成长之路---第一天---Python基础(5)---2015年12月26日(雾霾)

    六.流程控制 与C语言不通的事Python的流程控制的代码块不是用{}花括号表示的,而是用强制缩进来,而且缩进必须一致,官方推荐是使用4个空格,不建议使用使用tab(制表符)做缩进,一是不同的系统ta ...

  8. 我的Python成长之路---第一天---Python基础(3)---2015年12月26日(雾霾)

    四.变量和常量 变量是用来存储程序运行期间需要临时保存可以不断改变的数据的标识符.Python有自身的内存回收机制,所以在开发过程中不用考虑变量的销毁等 Python中的变量名命名有如下规则: 1.变 ...

  9. 我的Python成长之路---第一天---Python基础(2)---2015年12月26日(雾霾)

    三.数据类型 Python基本类型(能够直接处理的数据类型有以下几种)主要有5种 1.整数(int) Python可以处理任意大小的整数,当然包括负整数,在程序中的表示方法和数学上的写法一模一样,例如 ...

随机推荐

  1. HDU 3613 Best Reward(扩展KMP)

    [题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=3613 [题目大意] 一个字符串的价值定义为,当它是一个回文串的时候,价值为每个字符的价值的和,如果 ...

  2. windows下Qt Creator5.1.0编写程序以及调用OpenCV库

    系统说明 最近使用opencv编写程序,程序编的差不多就学习使用QT加个界面,首先声明下本人的系统和使用的软件版本, 系统: windows xp QT IDE:QT Creator5.1.0 Ope ...

  3. openssl命令行Base64编解码

    openssl对base64编解码的规范支持较差,用它编解码的结果别的语言如php处理很不方便,注意的几点整理如下 1,如果php加密结果做base64编码长度小于64,则需要添加一个换行符opens ...

  4. Android 架构【转】

    import java.util.ArrayList; import java.util.List;   import android.app.Activity; import android.app ...

  5. ios蓝牙开发(二)ios连接外设的代码实现

    上一篇文章介绍了蓝牙的技术知识,这里我们具体说明一下中心模式的应用场景.主设备(手机去扫描连接外设,发现外设服务和属性,操作服务和属性的应用.一般来说,外设(蓝牙设备,比如智能手环之类的东西), 会由 ...

  6. Jquery的一些取值

    //获取当前节点的html代码(包括当前节点),prop用于获取与设置Html元素的原生属性 $("#tmpMsgObj").prop("outerHTML") ...

  7. 最近用的到的一些js的常用方法(简单的)

    由于新的项目开始了,是使用MVC 5.0 开发的,前端使用了两个主流的框架 UIKIT,Ignite UI(收费) 因为是mvc主要用json来交互,不能避免要对前端脚本进行操作,所以就将能用到的方法 ...

  8. spring IOC简单入门

    spring的核心是ioc和aop 先介绍一下IOC(inverse of control控制反转)又叫DI(Dependency injection依赖注入) 个人理解为把对象的控制权由类转移到配置 ...

  9. Exponentiation

    Description Problems involving the computation of exact values of very large magnitude and precision ...

  10. 给内置对象或自定义对象添加存取器属性(getter setter)的方法总结

    funct = { get: function() { return this._x }, set: function(value) { this._x = value } } function Ob ...