• 1

代码1:

from multiprocessing import Pool
import os, time, random def long_time_task(name):
print('Run task %s (%s)...' % (name, os.getpid()))
start = time.time()
time.sleep(1)
#time.sleep(random.random() * 3)
end = time.time()
print('Task %s runs %0.2f seconds.' % (name, (end - start))) if __name__=='__main__':
print('Parent process %s.' % os.getpid())
p = Pool()
for i in range(4):
p.map_async(long_time_task, (i,))
#p.apply(long_time_task, args=(i,))
#p.apply_async(long_time_task, args=(i,))
print('Waiting for all subprocesses done...')
p.close()
p.join()
print('All subprocesses done.')

结果1:

# time python simple-2.py
Parent process 25144.
Waiting for all subprocesses done...
Run task 0 (25145)...
Run task 1 (25146)...
Run task 2 (25147)...
Run task 3 (25148)...
Task 0 runs 1.00 seconds.
Task 1 runs 1.00 seconds.
Task 2 runs 1.00 seconds.
Task 3 runs 1.00 seconds.
All subprocesses done. real 0m1.285s
user 0m0.158s
sys 0m0.053s
  • 代码2:

    使用 p.map(long_time_task, (i,))

结果2:

# time python simple-2.py
Parent process 25228.
Run task 0 (25229)...
Task 0 runs 1.00 seconds.
Run task 1 (25230)...
Task 1 runs 1.00 seconds.
Run task 2 (25231)...
Task 2 runs 1.00 seconds.
Run task 3 (25232)...
Task 3 runs 1.00 seconds.
Waiting for all subprocesses done...
All subprocesses done. real 0m4.302s
user 0m0.150s
sys 0m0.078s

结论:

使用map_async,可以并行运行,而map只能等待结束后继续运行;

apply_asyncapply 同理

  • 代码3:

……
p = Pool()
for i in range(8):
p.map_async(long_time_task, (i,)) ……

结果:

# time python simple-2.py
Parent process 25400.
Waiting for all subprocesses done...
Run task 0 (25401)...
Run task 1 (25402)...
Run task 2 (25403)...
Run task 3 (25404)...
Task 0 runs 1.00 seconds.
Task 2 runs 1.00 seconds.
Task 3 runs 1.00 seconds.
Task 1 runs 1.00 seconds.
Run task 4 (25401)...
Run task 5 (25404)...
Run task 6 (25402)...
Run task 7 (25403)...
Task 4 runs 1.00 seconds.
Task 5 runs 1.00 seconds.
Task 6 runs 1.00 seconds.
Task 7 runs 1.00 seconds.
All subprocesses done. real 0m2.292s
user 0m0.161s
sys 0m0.060s

结论:

只会创建4个进程,只有4个并行,多余任务的等待之前的进程结束后复用。

  • 代码4:
……
p = Pool(8)
for i in range(8):
p.map_async(long_time_task, (i,))
……

结果:

# time python simple-2.py
Parent process 26592.
Waiting for all subprocesses done...
Run task 0 (26593)...
Run task 1 (26594)...
Run task 2 (26595)...
Run task 3 (26596)...
Run task 4 (26597)...
Run task 5 (26598)...
Run task 6 (26599)...
Run task 7 (26600)...
Task 0 runs 1.00 seconds.
Task 3 runs 1.00 seconds.
Task 1 runs 1.00 seconds.
Task 2 runs 1.01 seconds.
Task 7 runs 1.01 seconds.
Task 5 runs 1.01 seconds.
Task 6 runs 1.01 seconds.
Task 4 runs 1.02 seconds.
All subprocesses done. real 0m1.310s
user 0m0.214s
sys 0m0.127s

结论:

可以看到4核心 跑8个任务,虽然创建了8个进程,但实际所用时间大于1秒,

因为只有4个并行,另外4个任务需要等待,但还是比 Pool(4) 快一点。

总结:

  • 进程自己不跑任务,进程通过进程里的线程跑任务;

  • GIL 作用于解释器上,一个解释器只能同时跑一个线程;

  • 因为gil的存在,多线程在python当中只能以时间片轮转的方式获得锁来执行;

  • 使用multiprocessing,可以创建多进程;

  • 所以使用 mul 可以实现并行跑任务;

  • 并发和并行的区别:

    并发是指同时创建任务,实际跑几个任务不知道;

    并行是指同时跑几个任务;

    举例:

    在4核心 CPU 上使用 Pool(8),有8个并发会创建8个进程,但是只有4个并行。

关于 GIL :

Python 代码的执行由 Python 虚拟机(也叫解释器主循环)来控制。Python 在设计之初就考虑到要在主循环中,同时只有一个线程在执行,就像单 CPU 的系统中运行多个进程那样,内存中可以存放多个程序,但任意时刻,只有一个程序在 CPU 中运行。同样的,虽然 Python 解释器中可以“运行”多个线程,但在任意时刻,只有一个线程在解释其中运行。

对 Python 虚拟机的访问由全局解释器锁(GIL)来控制,正是这个锁能保证同一时刻只有一个线程在运行。

学习multiprocessing(2)的更多相关文章

  1. 学习multiprocessing

    1. multiprocessing.Pool from multiprocessing.pool import Pool def gen_row(): ...return rows def main ...

  2. Python 多进程教程

    Python2.6版本中新添了multiprocessing模块.它最初由Jesse Noller和Richard Oudkerk定义在PEP 371中.就像你能通过threading模块衍生线程一样 ...

  3. python学习笔记——multiprocessing 多进程中的重构方法__init__

    重构: import multiprocessing import time class ClockProcesses(multiprocessing.Process): def __init__(s ...

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

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

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

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

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

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

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

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

  8. Python学习笔记18:标准库之多进程(multiprocessing包)

    我们能够使用subprocess包来创建子进程.但这个包有两个非常大的局限性: 1) 我们总是让subprocess执行外部的程序,而不是执行一个Python脚本内部编写的函数. 2) 进程间仅仅通过 ...

  9. python 3.x 学习笔记16 (队列queue 以及 multiprocessing模块)

    1.队列(queue) 用法: import queue q = queue.Queue() #先进先出模式 q.put(1) #存放数据在q里 作用: 1)解耦    2)提高效率 class qu ...

随机推荐

  1. background-size做自适应的背景图

    background-size做自适应的背景图 在我们做页面布局的时候往往会遇到这样的情况当我固定一个元素的尺寸,在像元素加入背景的时候发现背景图片的原始尺寸很大,当我把背景图写入时往往超过元素很大一 ...

  2. AngularJS 初学笔记(理论基础)

    AngularJS 是一个 JavaScript 框架.它是一个以 JavaScript 编写的库. AngularJS 通过 ng-directives 扩展了 HTML. ng-app 指令定义一 ...

  3. Scala 字段定义

    Scala 中定义字段只有val, var两种方式,都要在定义的同时即赋值,var 可以用占位符' _ '代替. 抽象类中定义的抽象字段不用赋初值,抽象方法也不用写方法体.(在子类中给抽象字段赋值和实 ...

  4. centos php 扩展安装

    1. 安装mysqli扩展 1.进入php源代码目录:# cd /home/apps/web/php/php-5.3.5/ 2.再进入要添加的mysqli扩展源码目录:# cd ext/mysqli/ ...

  5. Codeforces Round #346 (Div. 2) C Tanya and Toys

    C. Tanya and Toys 题目链接http://codeforces.com/contest/659/problem/C Description In Berland recently a ...

  6. 最近遇到的两个IE下的问题(IE兼容问题)

    最近遇到了两个IE下的兼容问题(产品目前还需要兼容IE8,所以没办法,运行效果虽然不好,但是也仍然兼容着吧) 问题描述: 1, 在更改IE窗口的时候,反应非常慢,甚至卡死 2, 在chrome运行正常 ...

  7. 1.1 java学习网站

    1.http://www.rupeng.com/Courses/Index/51 2.https://www.zhihu.com/question/25255189

  8. vs2013 中已经添加了引用,编译还是提示没有添加引用

    背景:在项目中需要引用wps中的etapi.dll.下载一个wps后,在项目中添加引用后. 同时在工程中使用using命令可以自动搜索进行添加该应用.但是,编译还是通不过.提示找不到excel.在网上 ...

  9. 5. test命令

    Shell中的 test 命令用于检查某个条件是否成立,它可以进行数值.字符和文件三个方面的测试. 1. 数值测试 参数 说明 -eq 等于则为真 -ne 不等于则为真 -gt 大于则为真 -ge 大 ...

  10. swift 图像的压缩上传

    func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [Str ...