zoukankan      html  css  js  c++  java
  • 使用gevent写异步代码

    并发编程(不是并行)目前有四种方式:多进程、多线程、协程和异步。

    多进程编程在python中有类似C的os.fork,更高层封装的有multiprocessing标准库
    多线程编程python中有Thread和threading
    异步编程在linux下主+要有三种实现select,poll,epoll
    协程在python中通常会说到yield,关于协程的库主要有greenlet,stackless,gevent,eventlet等实现。
    

    进程

    不共享任何状态
    调度由操作系统完成
    有独立的内存空间(上下文切换的时候需要保存栈、cpu寄存器、虚拟内存、以及打开的相关句柄等信息,开销大)
    通讯主要通过信号传递的方式来实现(实现方式有多种,信号量、管道、事件等,通讯都需要过内核,效率低)
    

    线程

    共享变量(解决了通讯麻烦的问题,但是对于变量的访问需要加锁)
    调度由操作系统完成(由于共享内存,上下文切换变得高效)
    一个进程可以有多个线程,每个线程会共享父进程的资源(创建线程开销占用比进程小很多,可创建的数量也会很多)
    通讯除了可使用进程间通讯的方式,还可以通过共享内存的方式进行通信(通过共享内存通信比通过内核要快很多)
    

    协程

    调度完全由用户控制
    一个线程(进程)可以有多个协程
    每个线程(进程)循环按照指定的任务清单顺序完成不同的任务(当任务被堵塞时,执行下一个任务;当恢复时,再回来执行这个任务;任务间切换只需要保存任务的上下文,没有内核的开销,可以不加锁的访问全局变量)
    协程需要保证是非堵塞的且没有相互依赖
    协程基本上不能同步通讯,多采用异步的消息通讯,效率比较高
    

    总结

    进程拥有自己独立的堆和栈,既不共享堆,亦不共享栈,进程由操作系统调度
    线程拥有自己独立的栈和共享的堆,共享堆,不共享栈,线程亦由操作系统调度(标准线程是的)
    协程和线程一样共享堆,不共享栈,协程由程序员在协程的代码里显示调度
    

    gevent是基于协程的Python网络库。特点:

    基于libev的快速事件循环(Linux上epoll,FreeBSD上kqueue)。
    基于greenlet的轻量级执行单元。
    API的概念和Python标准库一致(如事件,队列)。
    可以配合socket,ssl模块使用。
    能够使用标准库和第三方模块创建标准的阻塞套接字(gevent.monkey)。
    默认通过线程池进行DNS查询,也可通过c-are(通过GEVENT_RESOLVER=ares环境变量开启)。
    TCP/UDP/HTTP服务器
    子进程支持(通过gevent.subprocess)
    线程池
    

    import gevent
    from gevent.lock import Semaphore

    sem = Semaphore()
    def f1():
    for item in range(0,10):
    print('f1=>',item)
    gevent.sleep(3)
    def f2():
    for item in range(0,10):
    print('f2
    >',item)
    gevent.sleep(1)
    def f3():
    for item in range(0,10):
    sem.acquire()
    print('f3
    =>',item)
    sem.release()
    def f4():
    for item in range(0,10):
    sem.acquire()
    print('f4>',item)
    sem.release()
    def f5():
    for item in range(0,10):
    sem.acquire()
    print('f5
    =>',item)
    sem.release()
    gevent.sleep(2)
    def f6():
    for item in range(0,10):
    sem.acquire()
    print('f6
    ==>',item)
    sem.release()

    延时操作

    t1 = gevent.spawn(f1)
    t2 = gevent.spawn(f2)

    锁操作

    t3 = gevent.spawn(f3)
    t4 = gevent.spawn(f4)

    延时与锁

    t5 = gevent.spawn(f5)
    t6 = gevent.spawn(f6)
    gevent.joinall([t1,t2,t3,t4,t5,t6])

  • 相关阅读:
    User Get 'Access Denied' with Excel Service WebPart
    How To Search and Restore files from Site Collection Recycle Bin
    How To Collect ULS Log from SharePoint Farm
    How To Restart timer service on all servers in farm
    How to Operate SharePoint User Alerts with PowerShell
    How to get Timer Job History
    Synchronization Service Manager
    SharePoint 2007 Full Text Searching PowerShell and CS file content with SharePoint Search
    0x80040E14 Caused by Max Url Length bug
    SharePoint 2007 User Re-created in AD with new SID issue on MySite
  • 原文地址:https://www.cnblogs.com/lijintian/p/12877246.html
Copyright © 2011-2022 走看看