python 并发编程
2017-09-27 18:55
218 查看
概念
首先我们先了解下关于 并发与并行 的概念,这很容易让人混淆如果不注意的话,甚至会有人认为两者是一样的,统称为大家熟悉的并发编程;引用下Erlang之父的解释:
ConcurrentTwo queues and one coffee machine.
ParallelTwo queues and two coffee machines.
个人理解:
并发:可以理解为多个线程在单核上交替运行,每个线程都会分得一定的CPU时间片;
并行:可以理解为多个线程在多核上同时运行,每个线程都会独享一个CPU;
进程、线程、协程的区别:
进程:在Python中可以理解为仅只有进程可以称为并发编程,可以充分利用多核,它不像Java和C++,因为会受制于Python的GIL(Global Interpreter Lock)全局解释器锁。
线程:
Python的多线程在某种程度上讲是比较尴尬的存在,受制于Python的GIL(Global Interpreter Lock)全局解释器锁,阻止Python代码同时在多个处理器核心上运行,因为一个Python解释器在同一时刻只能运行于一个处理器之中。
1、对于CPU密集型计算, 并不能算真正的并行计算,不能发挥多核的作用;
2、对于IO 密集型(如爬虫等),由于GIL的原因,虽然在性能上优于单线程,但多线程的切换, 资源的申请释放 成本开销同样也是不可忽略的。
协程:
在线程与协程之间,个人更偏向于协程,
1、线程资源开销远大于协程, 线程它有自己的线程空间,在linux下可以理解为一个轻量级进程;
2、线程的上下文切换可能会引起寄存器和内存间的复制拷贝等;协程在进行切换时,是代码块进行切换(栈跳转),可以更多的利用CPU时间片;
编程样例:
多进程使用
# -*- encoding:utf8 -*- """ author: quanbin_zhu time : 2017/9/8 18:41 """ import multiprocessing #方法一:将要执行的方法作为参数传给Thread的构造方法 def work(id): time.sleep(1) print 'the process id is:%s' % id for i in xrange(3): p = multiprocessing.Process(target=work, args=(i,)) p.start() #方法二:从Process继承,并重写run() class WorkProcess(multiprocessing.Process): def __init__(self, id): multiprocessing.Process.__init__(self) self.id = id def run(self): print 'the process id is:%s' % self.id for i in xrange(3): p = WorkProcess(i) p.start()
多线程使用
# -*- encoding:utf8 -*- """ author: quanbin_zhu time : 2017/9/8 18:46 """ import threading import time #方法一:将要执行的方法作为参数传给Thread的构造方法 def show(id): time.sleep(1) print 'the thread id is:%s' % id for i in xrange(3): t =threading.Thread(target=show,args=(i,)) t.start() #方法二:从Thread继承,并重写run() class MyThread(threading.Thread): def __init__(self, id): super(MyThread, self).__init__() self.id = id def run(self): time.sleep(1) print 'the thread id is:%s' % self.id for i in xrange(3): t =MyThread(i) t.start()
多协程使用
# -*- encoding:utf8 -*- """ author: quanbin_zhu time : 2017/9/8 18:51 """ import gevent from gevent import monkey;monkey.patch_all() from gevent.pool import Pool from functools import partial class Task(gevent.Greenlet): def __init__(self, id): super(Task, self).__init__() self.task_id = id def _run(self): for index in xrange(1, 6): print "task id %s, output value %s" % (self.task_id, index) gevent.sleep(0) def show(id, f, t): for index in xrange(f, t): print "task id %s, output value %s" % (id, index) gevent.sleep(0) # 方法调用 def func_dispatch(): func = partial(show, f = 1, t=3) g1 = gevent.spawn(func, "gevent-01") g1.join() # 类调用 def class_dispatch(): tasks = [ Task(i) for i in xrange(0,3)] map(lambda t: t.start(), tasks) map(lambda t: t.join(), tasks) # 类和Pool结合调用 def class_dispatch_with_pool(): tasks = [Task(i) for i in xrange(0, 3)] pools = Pool(2) map(lambda t: pools.start(t), tasks) pools.join() if __name__ == '__main__': func_dispatch()
相关文章推荐
- python并发编程之多进程1-----------互斥锁与进程间的通信
- Python并发编程
- python_day10_并发编程
- python并发编程之IO模型
- Python并发编程的几篇文章
- Python网络编程之socketserver实现多并发
- Python学习-并发编程之线程池
- Python并发编程之进程
- python并发编程之多进程、多线程、异步和协程
- 《Python 编程实战:运用设计模式、并发和程序库创建高质量程序》阅读笔记
- Python并发编程
- 理解Python并发编程一篇就够了|线程篇
- Python并发编程eventlet
- Python全栈开发之并发编程
- Python学习-并发编程之进程池
- Python学习-并发编程之多线程
- python并发编程之多进程理论部分
- python并发编程之多进程、多线程、异步和协程详解
- Python并发编程之进程
- python_fullstack基础(十八)-并发编程-进程