资讯专栏INFORMATION COLUMN

python学习笔记 - fork, multiprocessing

littleGrow / 1834人阅读

摘要:近年来,人工智能的兴起使得更加火爆了。获取当前进程父进程的。但是唯一遗憾的是,函数只能在系统中使用,不能在系统中使用。因此在下,需要将其包含在中。则是立即返回一个可迭代对象。则是返回可迭代函数。

Python一直是一门对初学者非常友好的语言,在数据分析、Web 开发、网络安全、网络爬虫等方面应用广泛。近年来,人工智能的兴起使得 Python 更加火爆了。

我们在处理大量数据或者需要快速爬取多种网络资源的时候,我们无法避免使用到进程。Cpython 解释器中多线程涉及到 GIL 问题,我们这里暂不做考虑。

Python 实现多进程的方式有多种,我们下面一一来学习一下吧。

fork

Linux/Unix系统提供了一个非常特殊的函数fork().该函数在调用之后,调用它的进程会被复制一份,包括当前的RAM和接下来要执行的代码。
关于fork的具体内容可以阅读更多的文章:
http://blog.csdn.net/jason314...
http://blog.csdn.net/cywosp/a...

调用的fork()函数,它在主进程中返回的是子进程的pid;它在子进程中反馈的是0.
那么,我们就可以根据fork()函数返回的值来判断是在主进程中还是在子进程中了。
在Python中,为我们提供了os.fork()

import os

print "Process (%s) is running" % os.getpid()
i = 100
pid = os.fork()
if pid == 0:
    print "Son process (%s) is running" % os.getpid()
else:
    print "Main process (%s) is running" % os.getpid()

上面的代码用到了几个函数,罗列如下:

os.fork(),创建进程,在主进程中返回子进程的id,在子进程中返回0.

os.getpid() 获取到当前进程的id。

os.getppid() 获取当前进程父进程的id。

但是唯一遗憾的是,fork()函数只能在linuxunix系统中使用,不能在windows系统中使用。

multiprocessing

Python提供了跨平台的多进程支持,multiprocessing. multiprocessing模块提供了一个Process类代表一个进程。我们可以用Process创建一个进程。

from multiprocessing import Process
import time


def son_process(name):
    time.sleep(2)
    print "Process %s is running" % name


if __name__ == "__main__":
    son_process = Process(target=son_process, args=("Son",))
    print "Son process is started"
    son_process.start()
    son_process.join()
    print "Son process is ended - Printed by Main Process"

上面主要用到了

Process(target, attrs) 构造一个进程

process.start() 进程开始

process.join() 进程同步,Main进程序等待子程序完成后在执行后代码。

需要注意的是,在windows下,如果子进程序不是在__main__中创建的,那么就会出错。因为windows在创建子进程的时候,会将创建它的py文件import进去。import进去机会执行,那么就会不断地创建子进程,所以会出错。
因此在windows下,需要将其包含在__main__中。

Pool

上面的提到的Process主要用于创建一个进程,如何创建多个呢?Python在multiprocessing包里为我们提供了Pool类。
我们可以使用Pool.apply_async(func, args)函数来创建子进程。
代码:

from multiprocessing import Pool
import time


def son_process(name):
    time.sleep(5)
    print "Process %s is running
" % name


pool = Pool(4)
print "Son process is started"
for x in range(0, 10):
    pool.apply_async(son_process, args=("son_%d"%x,))
pool.close()
print "Mark"
pool.join()

print "Son process is ended - Printed by Main Process"

Pool(4)

join()

Wait for the worker processes to exit. One must call close() or terminate() before using join().即主进程会在.join()处等待worker进程们结束后再执行。

apply() 和 apply_async()

apply()apply_async()的区别就是前者是阻塞式的,后者是非阻塞式的。
阻塞式意思就是需要等待子进程完成后才能执行主线程后续的内容。
非阻塞意思就是无需等待子进程,两者是同步进行的。

map() 和 map_async()

跟高阶函数map()一致,Poolmap()函数是将一个可迭代对象的每一个元素作用域func
map也分阻塞和非阻塞。

imap() 和 imap_unordered()

imap 与 map的区别是,map是当所有的进程都已经执行完了,并将结果返回了,那么才返回map()函数的一个list结果。
imap()则是立即返回一个iterable可迭代对象。其迭代随着进行返回的结果而逐步迭代。

imap()和 imap_unordered()的区别

imap_unordered()不保证返回的结果顺序与进程添加的顺序一致。

怎么取得进程的结果?

阻塞式函数:
Pool.apply()直接返回结果
Pool.map() 直接返回一个list
非阻塞式函数
Pool.apply_async()和Pool.map_async() 返回一个AsyncResult对象。
AsyncResult对象具有:get()函数可以获取结果。
imap() imap_unordered()则是返回可迭代函数。

一个有用的函数 multiprocessing.cpu_count()

multiprocess.cpu_count()可以返回本计算机cpu的数量。
我们在新建一个进程池的时候,如果不填写任何参数,那么进程池的容量默认就是cpu的数量。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/38360.html

相关文章

  • python 学习笔记 - Queue & Pipes,进程间通讯

    摘要:的读写效率要高于。进程间的基于机制建立。当主进程创建子进程后,也被拷贝了一份。此后,关闭主进程的一个,关闭一个子进程的一个。据官方文档也是基于的实现。 上面写了Python如何创建多个进程,但是前面文章中创建的进程都是哑巴和聋子,自己顾自己执行,不会相互交流。那么如何让进程间相互说说话呢?Python为我们提供了一个函数multiprocessing.Pipe和一个类:multipro...

    xiaodao 评论0 收藏0
  • Python 多进程实践

    摘要:多进程的方式可以增加脚本的并发处理能力,支持这种多进程的编程方式在类系统中,的模块内置了函数用以创建子进程方式创建子进程执行结果从结果可以看到,从开始,下面的部分代码运行了两次,第一次是父进程运行,第二次是子进程运行,且子进程的的结果总是, 多进程的方式可以增加脚本的并发处理能力, python 支持这种多进程的编程方式 在类unix系统中, python的os 模块内置了fork 函...

    makeFoxPlay 评论0 收藏0
  • Python学习】windows环境不能用的函数

    摘要:普通的函数调用,调用一次,返回一次,但是调用一次,返回两次,因为操作系统自动把当前进程称为父进程复制了一份称为子进程,然后,分别在父进程和子进程内返回。子进程永远返回,而父进程返回子进程的。 一、Before Python学习过程中,经常发现教程上讲的函数在本机上会报错: AttributeError: module object has no attribute *** 作为一个初学...

    googollee 评论0 收藏0
  • threading + multiprocessing + logging = 死锁 ?

    摘要:后来通过调查发现是因为程序中同时使用了多线程,多进程以及模块,导致子进程中出现了死锁的情况。当创建子进程的时候,后台线程中的模块正好获取了一个锁在记录日志信息。 前段时间有个程序突然出现了子进程不工作的情况。 后来通过调查发现是因为程序中同时使用了多线程,多进程以及 logging 模块,导致子进程中出现了死锁的情况。 当创建子进程的时候,后台线程中的 logging 模块正好获取了一...

    netmou 评论0 收藏0

发表评论

0条评论

littleGrow

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<