python并行编程

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

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也需要花费时间的

时间: 2024-10-24 19:35:44

python并行编程的相关文章

Python并行编程的几个要点

一.基于线程的并行编程 如何使用Python的线程模块 如何定义一个线程 如何探测一个线程 如何在一个子类中使用线程 Lock和RLock实现线程同步 信号实现线程同步 条件(condition)实现线程同步 事件(event)实现线程同步 如何使用with语句 使用队列实现线程消息传递 如何评估多线程应用的性能 兑现成编程的危险 二.基于进程的并行编程 如何使用Python的multiprocessing模块 如何生成一个进程 如何命名一个进程 如何在后台运行一个进程 如何杀死一个进程 如何在

python并行编程学习之绪论

计算机科学的研究,不仅应该涵盖计算处理所基于的原理,还因该反映这些领域目前的知识状态.当今,计算机技术要求来自计算机科学所有分支的专业人员理解计算机处理的基础的关键,在于知道软件和硬件在所有层面上的交互. 直到现在,程序员可以依赖于硬件设计者,编译器和芯片厂商,来使他们的软件程序运行更快或者更有效,而无须改变他们的程序.但是,在实际中,如果一个程序运行的更快,它肯定是一个并行程序.尽管很多研究者的目标是保证程序员在编写他们的程序的时,无需注意硬件的并行特征,但是,要实现这一点,还将需要很多年的时

Python并行编程(十一):基于进程的并行

1.基本概念 多进程主要用multiprocessing和mpi4py这两个模块. multiprocessing是Python标准库中的模块,实现了共享内存机制,可以让运行在不同处理器核心的进程能读取共享内存. mpi4py库实现了消息传递的编程范例(设计模式).简单来说就是进程之间不靠任何共享信息来进行通讯,所有的交流都通过传递信息代替. 这与使用共享内存通讯.加锁或类似机制实现互斥的技术形成对比.在信息传递的代码中,进程通过send和receive进行交流. 2.创建一个进程 由父进程创建

Python并行编程(十):多线程性能评估

1.基本概念 GIL是CPython解释器引入的锁,GIL在解释器层面阻止了真正的并行运行.解释器在执行任何线程之前,必须等待当前正在运行的线程释放GIL,事实上,解释器会强迫想要运行的线程必须拿到GIL才能访问解释器的任何资源,例如栈或Python对象等,这也正是GIL的目的,为了阻止不同的线程并发访问Python对象.这样GIL可以保护解释器的内存,让垃圾回收工作正常.但事实上,这却造成了程序员无法通过并行执行多线程来提高程序的性能.如果我们去掉GIL,就可以实现真正的并行.GIL并没有影响

41 Python - python并行编程 多线程之——thread模块(已经过时,开发不推荐)

多线程并非并发编程的唯一技术手段,但是用的比较多的还是多线程. 001 单线程例子 创建文件 002 多线程例子 缺点没有控制进程结束的机制 _thread已经不推荐使用了(所以前面有有个下划线),学习阶段用于实验 (1)新建文件 函数_thread(第一个参数,第二个参数) 第一个参数,只需要写函数名,不用加括号 第二个参数,需要是元组形式 但是结果不正确,因为主线程没有等待子线程,一运行就结束了 (2)改进主线程让其等待子线程结束再结束 改进main函数,让主线程等待一下6秒等待子线程结束

40 Python - python并行编程 并行编程概述

原文地址:https://www.cnblogs.com/yijiexi/p/11165539.html

Python3 系列之 并行编程

进程和线程 进程是程序运行的实例.一个进程里面可以包含多个线程,因此同一进程下的多个线程之间可以共享线程内的所有资源,它是操作系统动态运行的基本单元:每一个线程是进程下的一个实例,可以动态调度和独立运行,由于线程和进程有很多类似的特点,因此,线程又被称为轻量级的进程.线程的运行在进程之下,进程的存在依赖于线程: 开胃菜 基于 Python3 创建一个简单的进程示例 from threading import Thread from time import sleep class CookBook

[python 并行2]线程

线程篇 基本使用 python线程使用的两个模块为: _thread (不推荐再使用). threading (查看threading的源码可以发现,threading实际是对_thread进一步的封装,官方将其称为 Low-level threading API,下面简单尝试使用_thread) ~~调用start_new_thread()函数生成新线程 函数声明:_thread.start_new_thread(function, args[, kwargs]) function: 子线程所

[python 并行3]进程

进程篇 基本使用 1 #coding=utf-8 import multiprocessing import os # 获取pid用 import time # 延时用 # 子进程要执行的函数 def child_proc(name): print(f'child process {name} pid: {os.getpid()}') time.sleep(3) print(f'{name} finish') # 主进程,必须在主模块中执行 if __name__ == '__main__':