• 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. Java之JSP基础语法

    1.JSP页面元素简介及page指令     2.JSP注释,3种不同注释 <!--  我是HTML注释,在客户端可见 --> <%--我是JSP注释,在客户端不可见 --%> ...

  2. Leetcode - 458 Poor Pigs

    题目: 总共有1000个罐子,其中有且只有1个是毒药,另外其他的都是水. 现在用一群可怜的猪去找到那个毒药罐. 已知毒药让猪毒发的时间是15分钟, 那么在60分钟之内,最少需要几头猪来找出那个毒药罐? ...

  3. 常用的js事件

    onmouseover:鼠标放上去时触发事件 onmouseout:鼠标从上面移开时触发事件 onclick:鼠标单击事件 onfocus:获得焦点 onblur:失去焦点 onchange:下拉菜单 ...

  4. CentOS安装glibc-2.14,错误安装libc.so.6丢失急救办法

    CentOS安装glibc-2.14,错误安装libc.so.6丢失急救办法   到http://ftp.gnu.org/gnu/glibc/下载glibc-2.14.tar.xz tar glibc ...

  5. overthewire朝花夕拾

    bandit: cat特殊字符文件名 - cat ./- 空格 cat "abc def"  or cat abc\ def 列出隐藏文件:ll du -ab 递归列出文件大小,以 ...

  6. java 方法学习

    手写随机代码 public class suiji{private static final int N = 200;private static final int LEFT = 40;privat ...

  7. 如何使用Java、Servlet创建二维码

    归功于智能手机,QR码逐渐成为主流,它们正变得越来越有用.从候车亭.产品包装.家装卖场.汽车到很多网站,都在自己的网页集成QR码,让人们快速找到它们.随着智能手机的用户量日益增长,二维码的使用正在呈指 ...

  8. USACO 2.3 Cow Pedigrees

    Cow Pedigrees Silviu Ganceanu -- 2003 Farmer John is considering purchasing a new herd of cows. In t ...

  9. js--性能优化(转)

    前言 一直在学习javascript,也有看过<犀利开发Jquery内核详解与实践>,对这本书的评价只有两个字犀利,可能是对javascript理解的还不够透彻异或是自己太笨,更多的是自己 ...

  10. Spring Security(12)——Remember-Me功能

    目录 1.1     概述 1.2     基于简单加密token的方法 1.3     基于持久化token的方法 1.4     Remember-Me相关接口和实现类 1.4.1    Toke ...