![](https://img-blog.csdnimg.cn/20201014180756928.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
Python并发编程
vettel2019
不要抱怨,不要嫉妒,做好自己
展开
-
1、操作系统介绍
操作系统介绍一、为什么要有操作系统现代的计算机系统主要是由一个或者多个处理器,主存,硬盘,键盘,鼠标,显示器,打印机,网络接口及其他输入输出设备组成。一般而言,现代计算机系统是一个复杂的系统。其一:如果每位应用程序员都必须掌握该系统所有的细节,那就不可能再编写代码了(严重影响了程序员的开发效率:全部掌握这些细节可能需要一万年....)其二:并且管理这些部件并加以优化使用,是一件...原创 2019-02-14 19:12:15 · 208 阅读 · 0 评论 -
3-9、线程queue
一 线程queuequeue is especially useful in threaded programming when information must be exchanged safely between multiple threads.有三种不同的用法class queue.Queue(maxsize=0) #队列:先进先出import queueq=que...原创 2019-02-15 09:56:56 · 60 阅读 · 0 评论 -
3-10、进程池与线程池
一 进程池与线程池在刚开始学多进程或多线程时,我们迫不及待地基于多进程或多线程实现并发的套接字通信,然而这种实现方式的致命缺陷是:服务的开启的进程数或线程数都会随着并发的客户端数目地增多而增多,这会对服务端主机带来巨大的压力,甚至于不堪重负而瘫痪,于是我们必须对服务端开启的进程数或线程数加以控制,让机器在一个自己可以承受的范围内运行,这就是进程池或线程池的用途,例如进程池,就是用来存放进程的池...原创 2019-02-15 09:58:34 · 92 阅读 · 0 评论 -
4-1、协程介绍
一 引子本节的主题是基于单线程来实现并发,即只用一个主线程(很明显可利用的cpu只有一个)情况下实现并发,为此我们需要先回顾下并发的本质:切换+保存状态cpu正在运行一个任务,会在两种情况下切走去执行其他的任务(切换由操作系统强制控制),一种情况是该任务发生了阻塞,另外一种情况是该任务计算的时间过长或有一个优先级更高的程序替代了它ps:在介绍进程理论时,提及进程的三种执行状态...原创 2019-02-16 18:26:43 · 86 阅读 · 0 评论 -
4-2、greenlet模块
一 greenlet模块如果我们在单个线程内有20个任务,要想实现在多个任务之间切换,使用yield生成器的方式过于麻烦(需要先得到初始化一次的生成器,然后再调用send。。。非常麻烦),而使用greenlet模块可以非常简单地实现这20个任务直接的切换#安装:pip3 install greenletfrom greenlet import greenletdef eat(nam...原创 2019-02-16 18:27:38 · 95 阅读 · 0 评论 -
4-3、gevent模块
一 gevent模块安装pip3 install geventGevent 是一个第三方库,可以轻松通过gevent实现并发同步或异步编程,在gevent中用到的主要模式是Greenlet, 它是以C扩展模块形式接入Python的轻量级协程。 Greenlet全部运行在主程序操作系统进程的内部,但它们被协作式地调度。#用法g1=gevent.spawn(func,1,,2,...原创 2019-02-16 18:28:41 · 179 阅读 · 0 评论 -
5-1、IO模型介绍
IO模型介绍同步: #所谓同步,就是在发出一个功能调用时,在没有得到结果之前,该调用就不会返回。按照这个定义,其实绝大多数函数都是同步调用。但是一般而言,我们在说同步、异步的时候,特指那些需要其他部件协作或者需要一定时间完成的任务。#举例:#1. multiprocessing.Pool下的apply #发起同步调用后,就在原地等着任务结束,根本不考虑任务是在计算还是在io阻塞,...原创 2019-02-16 18:32:21 · 107 阅读 · 0 评论 -
5-2、阻塞IO
阻塞IO(blocking IO)在linux中,默认情况下所有的socket都是blocking,一个典型的读操作流程大概是这样:当用户进程调用了recvfrom这个系统调用,kernel就开始了IO的第一个阶段:准备数据。对于network io来说,很多时候数据在一开始还没有到达(比如,还没有收到一个完整的UDP包),这个时候kernel就要等待足够的数据到来。而在用户进程...原创 2019-02-16 18:33:08 · 100 阅读 · 0 评论 -
5-3、非阻塞IO
非阻塞IO(non-blocking IO)Linux下,可以通过设置socket使其变为non-blocking。当对一个non-blocking socket执行读操作时,流程是这个样子:从图中可以看出,当用户进程发出read操作时,如果kernel中的数据还没有准备好,那么它并不会block用户进程,而是立刻返回一个error。从用户进程角度讲 ,它发起一个read操作后,并不需...原创 2019-02-16 18:33:57 · 79 阅读 · 0 评论 -
5-4、多路复用IO
多路复用IO(IO multiplexing)IO multiplexing这个词可能有点陌生,但是如果我说select/epoll,大概就都能明白了。有些地方也称这种IO方式为事件驱动IO(event driven IO)。我们都知道,select/epoll的好处就在于单个process就可以同时处理多个网络连接的IO。它的基本原理就是select/epoll这个function会不断...原创 2019-02-16 18:34:51 · 89 阅读 · 0 评论 -
5-5、异步IO
异步IO(Asynchronous I/O)Linux下的asynchronous IO其实用得不多,从内核2.6版本才开始引入。先看一下它的流程:用户进程发起read操作之后,立刻就可以开始去做其它的事。而另一方面,从kernel的角度,当它受到一个asynchronous read之后,首先它会立刻返回,所以不会对用户进程产生任何block。然后,kernel会等待数据准备完成,然...原创 2019-02-16 18:35:19 · 86 阅读 · 0 评论 -
5-6、IO模型比较分析
IO模型比较分析到目前为止,已经将四个IO Model都介绍完了。现在回过头来回答最初的那几个问题:blocking和non-blocking的区别在哪,synchronous IO和asynchronous IO的区别在哪。先回答最简单的这个:blocking vs non-blocking。前面的介绍中其实已经很明确的说明了这两者的区别。调用blocking IO会一直block住对应的...原创 2019-02-16 18:35:57 · 98 阅读 · 0 评论 -
3-8、信号量,Event,定时器
一 信号量信号量也是一把锁,可以指定信号量为5,对比互斥锁同一时间只能有一个任务抢到锁去执行,信号量同一时间可以有5个任务拿到锁去执行,如果说互斥锁是合租房屋的人去抢一个厕所,那么信号量就相当于一群路人争抢公共厕所,公共厕所有多个坑位,这意味着同一时间可以有多个人上公共厕所,但公共厕所容纳的人数是一定的,这便是信号量的大小from threading import Thread,Sema...原创 2019-02-15 09:56:08 · 184 阅读 · 0 评论 -
3-7、死锁现象和递归锁
一 死锁现象所谓死锁: 是指两个或两个以上的进程或线程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程,如下就是死锁from threading import Thread,Lockimport timemutexA=Lock()mutexB=Lock()clas...原创 2019-02-15 09:54:52 · 104 阅读 · 0 评论 -
3-6、GIL全局解释器锁
一 引子定义:In CPython, the global interpreter lock, or GIL, is a mutex that prevents multiple native threads from executing Python bytecodes at once. This lock is necessary mainly because CPython’s ...原创 2019-02-15 09:53:46 · 90 阅读 · 0 评论 -
2-1、进程理论
一 什么是进程进程:正在进行的一个过程或者说一个任务。而负责执行任务则是cpu。二 进程与程序的区别程序仅仅只是一堆代码而已,而进程指的是程序的运行过程。举例:想象一位有一手好厨艺的计算机科学家egon正在为他的女儿元昊烘制生日蛋糕。他有做生日蛋糕的食谱,厨房里有所需的原料:面粉、鸡蛋、韭菜,蒜泥等。在这个比喻中:做蛋糕的食谱就是程序(即用适当形式描述的算法)...原创 2019-02-14 19:16:55 · 102 阅读 · 0 评论 -
2-2、开启进程的两种方式
一 multiprocessing模块介绍python中的多线程无法利用多核优势,如果想要充分地使用多核CPU的资源(os.cpu\_count\(\)查看),在python中大部分情况需要使用多进程。Python提供了multiprocessing。 multiprocessing模块用来开启子进程,并在子进程中执行我们定制的任务(比如函数),该模块与多线程模块threading的编程接...原创 2019-02-14 19:21:12 · 138 阅读 · 0 评论 -
2-3、join方法
一 Process对象的join方法在主进程运行过程中如果想并发地执行其他的任务,我们可以开启子进程,此时主进程的任务与子进程的任务分两种情况情况一:在主进程的任务与子进程的任务彼此独立的情况下,主进程的任务先执行完毕后,主进程还需要等待子进程执行完毕,然后统一回收资源。情况二:如果主进程的任务在执行到某一个阶段时,需要等待子进程执行完毕后才能继续执行,就需要有一种机制能够让主进程检测...原创 2019-02-14 19:22:53 · 219 阅读 · 0 评论 -
2-5、互斥锁
一 互斥锁进程之间数据不共享,但是共享同一套文件系统,所以访问同一个文件,或同一个打印终端,是没有问题的,而共享带来的是竞争,竞争带来的结果就是错乱,如下#并发运行,效率高,但竞争同一打印终端,带来了打印错乱from multiprocessing import Processimport os,timedef work(): print('%s is running' %...原创 2019-02-14 19:25:51 · 113 阅读 · 0 评论 -
2-6、队列
队列介绍进程彼此之间互相隔离,要实现进程间通信(IPC),multiprocessing模块支持两种形式:队列和管道,这两种方式都是使用消息传递的创建队列的类(底层就是以管道和锁定的方式实现):Queue([maxsize]):创建共享的进程队列,Queue是多进程安全的队列,可以使用Queue实现多进程之间的数据传递。参数介绍:maxsize是队列中允许最大项数,省略则...原创 2019-02-14 19:26:58 · 129 阅读 · 1 评论 -
2-7、生产者消费者模型
一 生产者消费者模型介绍为什么要使用生产者消费者模型生产者指的是生产数据的任务,消费者指的是处理数据的任务,在并发编程中,如果生产者处理速度很快,而消费者处理速度很慢,那么生产者就必须等待消费者处理完,才能继续生产数据。同样的道理,如果消费者的处理能力大于生产者,那么消费者就必须等待生产者。为了解决这个问题于是引入了生产者和消费者模式。什么是生产者和消费者模式生产者消费者模式是通过...原创 2019-02-14 19:28:19 · 128 阅读 · 1 评论 -
3-1、线程理论
一 什么是线程在传统操作系统中,每个进程有一个地址空间,而且默认就有一个控制线程线程顾名思义,就是一条流水线工作的过程(流水线的工作需要电源,电源就相当于cpu),而一条流水线必须属于一个车间,一个车间的工作过程是一个进程,车间负责把资源整合到一起,是一个资源单位,而一个车间内至少有一条流水线。所以,进程只是用来把资源集中到一起(进程只是一个资源单位,或者说资源集合),而线程才是cpu...原创 2019-02-15 09:38:01 · 78 阅读 · 0 评论 -
3-2、开启线程的两种方式
一 threading模块介绍multiprocess模块的完全模仿了threading模块的接口,二者在使用层面,有很大的相似性,因而不再详细介绍二 开启线程的两种方式方式一from threading import Threadimport timedef sayhi(name): time.sleep(2) print('%s say hello' %...原创 2019-02-15 09:38:10 · 88 阅读 · 0 评论 -
3-3、多线程和多进程的区别
一 谁的开启速度快?1、在主进程下开启线程from threading import Threaddef work(): print('hello')if __name__ == '__main__': t=Thread(target=work) t.start() print('主线程/主进程')执行结果如下,几乎是t.start ()的同...原创 2019-02-15 09:48:42 · 237 阅读 · 1 评论 -
3-4、Thread对象的其他属性或方法
Thread对象的其他属性或方法介绍Thread实例对象的方法 # isAlive(): 返回线程是否活动的。 # getName(): 返回线程名。 # setName(): 设置线程名。threading模块提供的一些方法: # threading.currentThread(): 返回当前的线程变量。 # threading.enumerate(): 返回一...原创 2019-02-15 09:49:36 · 86 阅读 · 0 评论 -
3-5、守护线程
一 守护线程无论是进程还是线程,都遵循:守护xxx会等待主xxx运行完毕后被销毁需要强调的是:运行完毕并非终止运行1、对主进程来说,运行完毕指的是主进程代码运行完毕2、对主线程来说,运行完毕指的是主线程所在的进程内所有非守护线程统统运行完毕,主线程才算运行完毕详细解释:1、主进程在其代码结束后就已经算运行完毕了(守护进程在此时就被回收),然后主进程会一直等非守护的子进...原创 2019-02-15 09:52:10 · 62 阅读 · 0 评论 -
5-7、selectors模块
一 了解select,poll,epollIO复用:为了解释这个名词,首先来理解下复用这个概念,复用也就是共用的意思,这样理解还是有些抽象,为此,咱们来理解下复用在通信领域的使用,在通信领域中为了充分利用网络连接的物理介质,往往在同一条网络链路上采用时分复用或频分复用的技术使其在同一链路上传输多路信号,到这里我们就基本上理解了复用的含义,即公用某个“介质”来尽可能多的做同一类(性质)的...原创 2019-02-16 18:39:29 · 116 阅读 · 0 评论