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

多进程 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: [email protected]

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: [email protected]

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: [email protected]

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: [email protected]

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

时间: 2024-10-21 22:07:22

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

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

多线程编程 什么是多线程,线程是操作系统能够进行运算调度的最小单位.他包含在进程之中,是进程中的实际运作单位.线程是进程中一个单顺序的空值六,一个进程可以并发多个线程,每个线程可以并行处理不同的任务. threading模块 python的标准库提供了两个模块用于多线程处理,_thread和threading,_thread是低级模块,threading是高级模块,是对_thread进行了封装. 启动一个线程就是把一个函数传入并创建Thread实例,然后调用start()开始执行: 线程有两种调

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

socketserver 之前讲道德socket模块是单进程的,只能接受一个客户端的连接和请求,只有当该客户端断开的之后才能再接受来自其他客户端的连接和请求.当然我们也可以通过python的多线程等模块自己写一个可以同时接收多个客户端连接和请求的socket.但是这完全没有必要,因为python标准库已经为我们内置了一个多线程的socket模块socketserver,我们直接调用就可以了,完全没有必要重复造轮子. 我们只需简单改造一下之前的socket演示程序的服务端就可以了,客户端不用变 1

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

2015年12月26日是个特别的日子,我的Python成之路迈出第一步.见到了心目中的Python大神(Alex),也认识到了新的志向相投的伙伴,非常开心. 尽管之前看过一些Python的视频.书,算是有一点基础.但在这里我要保持空杯心态,一切从头开始.好了不多说,Let's Python!!!! 一.Python简介 Python是著名的“龟叔”Guido van Rossum在1989年圣诞节期间,为了打发无聊的圣诞节而编写的一个编程语言.目前Python已经成为实际上除了中国最流行的开发语

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

三.数据类型 Python基本类型(能够直接处理的数据类型有以下几种)主要有5种 1.整数(int) Python可以处理任意大小的整数,当然包括负整数,在程序中的表示方法和数学上的写法一模一样,例如:1,100,-8080,0,等等. 2.浮点数(float) 浮点数也就是数学中的小数.由于整数和浮点数在计算机内部存储的方式是不同的,整数运算永远是精确的,而浮点数运算则可能会有四舍五入的误差.需要注意. 3.字符串 字符串是以单引号'或双引号"括起来的任意文本,比如'abc',"xy

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

七.列表——list Python的列表是一种内置的数据类型,是由Python的基本数据类型组成的有序的集合.有点类似C语言的数组,但与数组不同的是,Python在定义列表的时候不用指定列表的容积(长度),可根据需要任意扩展,另外列表的内的元素可以是不同的数据类型,当然既然是任何数据类型,当然也包括另一个列表也就是嵌套.Python中列表使用中括号[]括起来,例如[1,2,True,'ABC',[5,'678']]. 1.列表的切片 通字符串一样列表也支持切片操作,例如我们有一个列表A_list

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

四.变量和常量 变量是用来存储程序运行期间需要临时保存可以不断改变的数据的标识符.Python有自身的内存回收机制,所以在开发过程中不用考虑变量的销毁等 Python中的变量名命名有如下规则: 1.变量名必须是字母.数字和下划线的组合 2.数字不能开头 3.不能使用Python保留的关键字入print.id等(注意这个不是Python强制的,但是如果使用关键字定义了会是改变关键原来的用途) 关于变量名的一些建议: 1.变量名最好有意义,尽量不要使用a = 1, x = 'ABC',var = 1

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

数据类型之字典 一.字典简介 字典dict(dictionary),在其他语言中也成为map,使用键-值(key-value)的形式存储和展现,具有极快的查找速度. 字典的定义 d = {'key':value,...} 字典可以嵌套,value也可以使用列表等数据类型 字典通过键获取键所对应的值 d[key] 二.字典常用方法 1.clear(清除字典所有元素) 代码: 1 def clear(self): # real signature unknown; restored from __d

我的Python成长之路---第一天---Python基础(作业1:登录验证)---2015年12月26日(雾霾)

1 #!/usr/bin/env python3 2 # coding:utf-8 3 ''' 4 Created on: 2015年12月29日 5 6 @author: 张晓宇 7 8 Email: [email protected] 9 10 Version: 1.0 11 12 Description: 输入用户名密码,认证成功显示欢迎信息,认证失败,输错三次后锁定 13 14 Help: 15 ''' 16 import os 17 # 定义用户信息写入函数,用于把用户信息写回文件 1

我的Python成长之路---第一天---Python基础(作业2:三级菜单)---2015年12月26日(雾霾)

#!/usr/bin/env python3 # coding:utf-8 ''' Created on: 2015年12月30日 @author: 张晓宇 Email: [email protected] Version: 1.0 Description: 三层菜单 1.菜单一共三级即:省,市,区县 2.每一级菜单输入的如果输入的是菜单里的选项则进入下级菜单 3.第1级菜单输入q退出系统 4.第2.3级菜单输入q退出系统,输入b返回上级菜单 5.三级菜单全部正确打印最后的全部选择结果,否则继续