python IO多路 IO多路复用+socket实现 协程

 1. IO多路复用

  IO多路复用作用:检测多个socket是否已经发生变化(是否已经连接成功/是否已经获取数据)(可读/可写)
 
 2. 基于IO多路复用+socket实现并发请求(一个线程100个请求)

    IO多路复用          socket非阻塞

  
    基于事件循环实现的异步非阻塞框架:lzl
     非阻塞:不等待
        异步:执行完某个人物后自动调用我给他的函数。
    Python中开源 基于事件循环实现的异步非阻塞框架 Twisted

3.IO多路复用作用?
     检测多个socket是否发生变化。
     操作系统检测socket是否发生变化,有三种模式:
        select:最多1024个socket;循环去检测。
        poll:不限制监听socket个数;循环去检测(水平触发)。
        epoll:不限制监听socket个数;回调方式(边缘触发)。

Python模块:
      select.select
      select.epoll   

4.提高并发方案 : 

    多进程

    多线程

    异步非阻塞模块  (Twisted) scrapy框架(单线程完成并发)的大V大V

 

 

5.什么是异步非阻塞?

    非阻塞 , 不等待

      比如创建socket对某个地址进行connect、获取接收数据recv时默认都会等待(连接成功或接收到数据),才执行后续操作。
          如果设置setblocking(False),以上两个过程就不再等待,但是会报BlockingIOError的错误,只要捕获即可。
         异步,通知,执行完成之后自动执行回调函数或自动执行某些操作(通知)。
    比如做爬虫中向某个地址baidu.com发送请求,当请求执行完成之后自执行回调函数。

6.什么是同步阻塞 ?

    阻塞 : 等

    同步 : 按照顺序逐步执行

 

 

 3. 协程

  感念 : 

    进程 , 操作系统中不存在

    线程 , 操作系统中不存在

    协程 , 是由程序员创造出来的一个不是真实存在的东西

  协程 : 是微线程,对一个线程进程分片 , 使得线程在代码块之间来回切换执行 , 而不是在原来逐行执行 。

 注意 : 单纯的协程无用

协程 +   遇到IO就切换             pip3  install   gevent

代码中遇到  IO 都会自动执行  greenlet 的switch  进行切换 

from gevent import monkey
monkey.patch_all() # 以后代码中遇到IO都会自动执行greenlet的switch进行切换
import requests
import gevent


def get_page1(url):
    ret = requests.get(url)
    print(url,ret.content)

def get_page2(url):
    ret = requests.get(url)
    print(url,ret.content)

def get_page3(url):
    ret = requests.get(url)
    print(url,ret.content)

gevent.joinall([
    gevent.spawn(get_page1, 'https://www.python.org/'), # 协程1
    gevent.spawn(get_page2, 'https://www.yahoo.com/'),  # 协程2
    gevent.spawn(get_page3, 'https://github.com/'),     # 协程3
])

1.什么是协程 : 

  协程可以称为"微线程" , 就是开发者控制线程执行流程 , 控制先执行某段代码然后在切换到另外执行代码....来回切换

2.协程可以提高并发吗 : 

  协程自己本身无法实现并发(可能性能会降低)

  协程 + IO切换性能高

3.单线程提供并发 : 

  协程  IO    切换 (gevent)

  基于事件循坏的异步非阻塞框架 :  Twisted

 

手动实现协程 :  yield关键字生成器

def f1():
    print(11)
    yield
    print(22)
    yield
    print(33)

def f2():
    print(55)
    yield
    print(66)
    yield
    print(77)

v1 = f1()
v2 = f2()

next(v1) # v1.send(None)
next(v2) # v1.send(None)
next(v1) # v1.send(None)
next(v2) # v1.send(None)
next(v1) # v1.send(None)
next(v2) # v1.send(None)
手动实现协程 yield

4. 进程 , 线程 , 协程的区别 ?

进程 :是资源分配的最小单元 , 其作用是进行数据隔离 ,

线程 :是cpu调度的最小单元 , 其作用主要是执行某个任务,

后来程序员为了让代码更牛逼 , 创建了协程 , 协程本身不存在 , 是程序员自己创造出来的 , 

协程 : 可以对代码的执行顺序进行控制 ,        本身协程存在没有意义 , 但是协程要是和IO放在一起 就很牛逼。

遇到IO操作就切换 , 相当于把一个线程分片 , 所达到的效果是线程一直没有停 , 一直在工作 , 

这就是进程 , 线程 , 协程 , 的本质区别 , 在python中用协程的时候会有一个模块叫greenlet , 

协程加IO自动切换的模块叫gevent

 

一个应用程序可以有多个进程 , 一个进程可以有多个线程 ,

其他语言几乎很少用进程 , 都是用线程 ,     

对于python来说 : IO操作主要用多线程实现 , 计算密集型操作主要是用多进程实现 。

主要原因 : python中存在GIL锁 , GIL锁的作用就是保证一个进程中同一时刻只有一个线程被cpu调度

所以在python中想要利用cpu的多核优势就是开多个进程 。 

5.异步非阻塞

6.IO多路复用

    作用: 可以监听所有的IO请求状态 。

     三种模式 : 

        select

        poll

        epoll

  

 

 

 

 

 


 

posted on 2018-09-14 00:47  帆总、欧巴  阅读(281)  评论(0编辑  收藏  举报

导航