码迷,mamicode.com
首页 > 编程语言 > 详细

python并行编程

时间:2017-07-05 01:21:07      阅读:377      评论:0      收藏:0      [点我收藏+]

标签:条件   alt   高效   电脑   proc   join   调用   strong   机器学习   

并行编程的思想:分而治之,有两种模型

1.MapReduce:将任务划分为可并行的多个子任务,每个子任务完成后合并得到结果

例子:统计不同形状的个数。

技术分享

先通过map进行映射到多个子任务,分别统计个数,然后在用reduce进行归纳一下。

2.流水:将任务分为串行的多个子任务,每个子任务并行。ProductConsume

例子:

技术分享

多个生产者进行并行,多个消费者进行并行。生产者生产出来东西放到队列里;队列里有东西时,消费者就可以进行消费,这样双方没有太大的依赖关系。

 

为什么要并行编程呢?

多核,云计算,使得实现并行编程的条件更容易满足。

大数据(导致数据多),机器学习(复杂),高并发,使得并行编程很必要。

 

为什么很少用呢?

任务分割,共享数据的访问,死锁,互斥,信号量,利用管道,队列通信。线程,进程的管理。

这些概念使得并行编程的实现看上去很难

 

怎么学并行编程?

库:  Threading,实现多线程

    Multiprocess,实现多进程

    Parallepython,实现分布式计算,同时解决CPU和网络资源受限问题。

    Celery+RabbitMQ/Redis,可实现分布式任务队列 Django和它搭配可实现异步任务队列

    Gevent,可实现高效异步IO,协成

 

2.进程和线程

CPU同一时刻只能调度一个进程,进程之间memory独立,进程内线程共享memory。

 

我们主要解决的问题是:

进程间通信问题;

线程间同步问题

技术分享

 

例子:计算10000000000自减到0,然后用多进程和多线程计算,看看他们用时多久

 

# -*- coding: utf-8 -*-
# CopyRight by heibanke

import time
from threading import Thread
from multiprocessing import Process

def countdown(n):
    while n > 0:
        n -= 1
        
        
COUNT = 100000000 # 1亿

def thread_process_job(n, Thread_Process, job):
    """
    n: 多线程或多进程数
    Thread_Process: Thread/Process类 
    job: countdown任务
    """
    local_time=time.time()

    #实例化多线程或多进程
    threads_or_processes = [Thread_Process(target=job,args=(COUNT//n,)) for i in xrange(n)]#学习这种写法,很高大上,把不同的类放到列表里边
    #threads_or_processes中保存了三个Thread_process个对象
    
    for t in threads_or_processes:
        t.start() #开始线程或进程,必须调用
    for t in threads_or_processes:
        t.join() #等待直到该线程或进程结束
        #join的作用是阻塞进程,直到所有的线程执行完毕之后,才可以执行后边的语句
    
    print n,Thread_Process.__name__," run job need ",time.time()-local_time
    

if __name__=="__main__":
    print "Multi Threads"
    for i in [1,2,4]:
        thread_process_job(i,Thread, countdown)
        
    print "Multi Process"
    for i in [1,2,4]:
        thread_process_job(i,Process, countdown)        

输出结果:

技术分享

从结果中看出来,多线程时,随着线程的增多,时间反而更多;多进程随着进程的增多,时间变少。原因是python的GIL机制

GIL

当有多个线程的时候,并不是真的是并行运行的,实际上有一个锁,谁申请到了谁运行

在python的原始解释器CPython中存在着GIL(Global Interpreter Lock,全局解释器锁),因此在解释执行python代码时,会产生互斥锁来限制线程对共享资源的访问,直到解释器遇到I/O操作或者操作次数达到一定数目时才会释放GIL。

所以,虽然CPython的线程库直接封装了系统的原生线程,但CPython整体作为一个进程,同一时间只会有一个获得GIL的线程在跑,其他线程则处于等待状态。这就造成了即使在多核CPU中,多线程也只是做着分时切换而已。

所以它更适合处理I/O密集型的任务,不适合处理CPU密集型的任务。

不过muiltprocessing的出现,已经可以让多进程的python代码编写简化到了类似多线程的程度了。(链接:https://www.zhihu.com/question/23474039/answer/35418893)



技术分享

这是两个线程在运行,并不是并行,而是串行,红色的线表示在申请cpu

 

技术分享

四个线程在运行

 

进程可以快,而线程反而慢的原因是,我的电脑有多个核,进程可以进行并行的,而线程在python里边还是串行的,申请cpu也需要花费时间的

 

python并行编程

标签:条件   alt   高效   电脑   proc   join   调用   strong   机器学习   

原文地址:http://www.cnblogs.com/shixisheng/p/7119217.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!