gevent

GitHub - gevent/gevent: Coroutine-based concurrency library for Python https://github.com/gevent/gevent

gevent - 廖雪峰的官方网站 https://www.liaoxuefeng.com/wiki/001374738125095c955c1e6d8bb493182103fac9270762a000/001407503089986d175822da68d4d6685fbe849a0e0ca35000

Python通过yield提供了对协程的基本支持,但是不完全。而第三方的gevent为Python提供了比较完善的协程支持。

gevent是第三方库,通过greenlet实现协程,其基本思想是:

当一个greenlet遇到IO操作时,比如访问网络,就自动切换到其他的greenlet,等到IO操作完成,再在适当的时候切换回来继续执行。由于IO操作非常耗时,经常使程序处于等待状态,有了gevent为我们自动切换协程,就保证总有greenlet在运行,而不是等待IO。

Design — Gunicorn 19.9.0 documentation
http://docs.gunicorn.org/en/stable/design.html#async-workers

eventlet-没有孙子worker.png

请求发来前运行后.png

worker 数固定

请求发来后-初始阶段-每个子worker新增孙worker.png

请求发来后-进行阶段-随着jmeter-线程数和循环数的增加-worker增加.png

https://www.tornadoweb.org/en/stable/guide/async.html#asynchronous

systems like gevent use lightweight threads to offer performance comparable to asynchronous systems, but they do not actually make things asynchronous

Asynchronous
An asynchronous function returns before it is finished, and generally causes some work to happen in the background before triggering some future action in the application (as opposed to normal synchronous functions, which do everything they are going to do before returning). There are many styles of asynchronous interfaces:

Callback argument

Return a placeholder (Future, Promise, Deferred)

Deliver to a queue

Callback registry (e.g. POSIX signals)

Regardless of which type of interface is used, asynchronous functions by definition interact differently with their callers; there is no free way to make a synchronous function asynchronous in a way that is transparent to its callers (systems like gevent use lightweight threads to offer performance comparable to asynchronous systems, but they do not actually make things asynchronous).

Asynchronous operations in Tornado generally return placeholder objects (Futures), with the exception of some low-level components like the IOLoop that use callbacks. Futures are usually transformed into their result with the await or yield keywords.

Here is a sample synchronous function:

from tornado.httpclient import HTTPClient

def synchronous_fetch(url):
http_client = HTTPClient()
response = http_client.fetch(url)
return response.body
And here is the same function rewritten asynchronously as a native coroutine:

from tornado.httpclient import AsyncHTTPClient

async def asynchronous_fetch(url):
http_client = AsyncHTTPClient()
response = await http_client.fetch(url)
return response.body
Or for compatibility with older versions of Python, using the tornado.gen module:

from tornado.httpclient import AsyncHTTPClient
from tornado import gen

@gen.coroutine
def async_fetch_gen(url):
http_client = AsyncHTTPClient()
response = yield http_client.fetch(url)
raise gen.Return(response.body)
Coroutines are a little magical, but what they do internally is something like this:

from tornado.concurrent import Future

def async_fetch_manual(url):
http_client = AsyncHTTPClient()
my_future = Future()
fetch_future = http_client.fetch(url)
def on_fetch(f):
my_future.set_result(f.result().body)
fetch_future.add_done_callback(on_fetch)
return my_future
Notice that the coroutine returns its Future before the fetch is done. This is what makes coroutines asynchronous.

Anything you can do with coroutines you can also do by passing callback objects around, but coroutines provide an important simplification by letting you organize your code in the same way you would if it were synchronous. This is especially important for error handling, since try/except blocks work as you would expect in coroutines while this is difficult to achieve with callbacks. Coroutines will be discussed in depth in the next section of this guide.

异步 在完成之前返回

协程 返回未来

小结:

1、

micro-thread with no implicit scheduling; coroutines, in other words.

没有显式调度的微线程,换言之 协程

2、

一个greenlet切换到另一个greenlet,前者被suspend推迟、暂停

uWSGI项目 — uWSGI 2.0 文档 https://uwsgi-docs-zh.readthedocs.io/zh_CN/latest/#

循环引擎 (实现事件和并发,组件可以在reforking, threaded, asynchronous/evented和green thread/coroutine模式下运行。支持多种技术,包括uGreen, Greenlet, Stackless, Gevent, Coro::AnyEvent, Tornado, Goroutines和Fibers)

greenlet: Lightweight concurrent programming — greenlet 0.4.0 documentation
https://greenlet.readthedocs.io/en/latest/#greenlet-lightweight-concurrent-programming

The “greenlet” package is a spin-off of Stackless, a version of CPython that supports micro-threads called “tasklets”. Tasklets run pseudo-concurrently (typically in a single or a few OS-level threads) and are synchronized with data exchanges on “channels”.

A “greenlet”, on the other hand, is a still more primitive notion of micro-thread with no implicit scheduling; coroutines, in other words. This is useful when you want to control exactly when your code runs. You can build custom scheduled micro-threads on top of greenlet; however, it seems that greenlets are useful on their own as a way to make advanced control flow structures. For example, we can recreate generators; the difference with Python’s own generators is that our generators can call nested functions and the nested functions can yield values too. (Additionally, you don’t need a “yield” keyword. See the example in test/test_generator.py).

Greenlets are provided as a C extension module for the regular unmodified interpreter.

greenlet: Lightweight concurrent programming — greenlet 0.4.0 documentation
https://greenlet.readthedocs.io/en/latest/#introduction

A “greenlet” is a small independent pseudo-thread. Think about it as a small stack of frames; the outermost (bottom) frame is the initial function you called, and the innermost frame is the one in which the greenlet is currently paused. You work with greenlets by creating a number of such stacks and jumping execution between them. Jumps are never implicit: a greenlet must choose to jump to another greenlet, which will cause the former to suspend and the latter to resume where it was suspended. Jumping between greenlets is called “switching”.

When you create a greenlet, it gets an initially empty stack; when you first switch to it, it starts to run a specified function, which may call other functions, switch out of the greenlet, etc. When eventually the outermost function finishes its execution, the greenlet’s stack becomes empty again and the greenlet is “dead”. Greenlets can also die of an uncaught exception.

https://www.tornadoweb.org/en/stable/#threads-and-wsgi

Threads and WSGI

一个进程一个线程

Tornado is different from most Python web frameworks. It is not based on WSGI, and it is typically run with only one thread per process. See the User’s guide for more on Tornado’s approach to asynchronous programming.

While some support of WSGI is available in the tornado.wsgi module, it is not a focus of development and most applications should be written to use Tornado’s own interfaces (such as tornado.web) directly instead of using WSGI.

In general, Tornado code is not thread-safe. The only method in Tornado that is safe to call from other threads is IOLoop.add_callback. You can also use IOLoop.run_in_executor to asynchronously run a blocking function on another thread, but note that the function passed to run_in_executor should avoid referencing any Tornado objects. run_in_executor is the recommended way to interact with blocking code.

https://www.tornadoweb.org/en/stable/guide/async.html#asynchronous-and-non-blocking-i-o

Real-time web features require a long-lived mostly-idle connection per user. In a traditional synchronous web server, this implies devoting one thread to each user, which can be very expensive.

To minimize the cost of concurrent connections, Tornado uses a single-threaded event loop. This means that all application code should aim to be asynchronous and non-blocking because only one operation can be active at a time.

The terms asynchronous and non-blocking are closely related and are often used interchangeably, but they are not quite the same thing.

传统同步web服务,给每个用户一个线程 Tornado使用单线程的事件循环 这要求应用代码是异步的、非阻塞的,因为同时置疑一个操作时活跃的

based on Greenlets (via Eventlet and Gevent) fork 孙子worker 比较 gevent不是异步 协程原理 占位符 placeholder (Future, Promise, Deferred) 循环引擎 greenlet 没有显式调度的微线程,换言之 协程的更多相关文章

  1. 循环引擎 greenlet 没有显式调度的微线程,换言之 协程

    小结: 1. micro-thread with no implicit scheduling; coroutines, in other words. 没有显式调度的微线程,换言之 协程 2. 一个 ...

  2. based on Greenlets (via Eventlet and Gevent) fork 孙子worker 比较

    Design — Gunicorn 19.9.0 documentationhttp://docs.gunicorn.org/en/stable/design.html#async-workers e ...

  3. paip.提升性能---协程“微线程”的使用.

    paip.提升性能---协程的使用. 近乎无限并发的"微线程" 作者Attilax  艾龙,  EMAIL:1466519819@qq.com 来源:attilax的专栏 地址:h ...

  4. Python学习之路--进程,线程,协程

    进程.与线程区别 cpu运行原理 python GIL全局解释器锁 线程 语法 join 线程锁之Lock\Rlock\信号量 将线程变为守护进程 Event事件 queue队列 生产者消费者模型 Q ...

  5. 11.python之线程,协程,进程,

    一,进程与线程 1.什么是线程 线程是操作系统能够进行运算调度的最小单位.它被包含在进程之中,是进程中的实际运作单位.一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行 ...

  6. 文成小盆友python-num11-(1) 线程 进程 协程

    本节主要内容 线程补充 进程 协程 一.线程补充 1.两种使用方法 这里主要涉及两种使用方法,一种为直接使用,一种为定义自己的类然后继承使用如下: 直接使用如下: import threading d ...

  7. python自动化开发-[第十天]-线程、协程、socketserver

    今日概要 1.线程 2.协程 3.socketserver 4.基于udp的socket(见第八节) 一.线程 1.threading模块 第一种方法:实例化 import threading imp ...

  8. Python线程和协程-day10

    写在前面 上课第10天,打卡: 感谢Egon老师细致入微的讲解,的确有学到东西! 一.线程 1.关于线程的补充 线程:就是一条流水线的执行过程,一条流水线必须属于一个车间: 那这个车间的运行过程就是一 ...

  9. python线程、协程、I/O多路复用

    目录: 并发多线程 协程 I/O多路复用(未完成,待续) 一.并发多线程 1.线程简述: 一条流水线的执行过程是一个线程,一条流水线必须属于一个车间,一个车间的运行过程就是一个进程(一个进程内至少一个 ...

随机推荐

  1. 利用 Watermill 实现 Golang CQRS

    CQRS CQRS 的意思是"命令-查询责任隔离".我们分离了命令(写请求)和查询(读请求)之间的责任.写请求和读请求由不同的对象处理. 就是这样.我们可以进一步分割数据存储,使用 ...

  2. 什么是可变参数?如何创建不可变集合?Steam三类方法是什么?获取流方法特点?流中间方法特点?终结流方法特点?

    ==知识梳理== ==重难点梳理== ==今日目标== 1.能够了解什么是可变参数 2.能够了解如何去创建不可变集合 3.能够掌握Stream流的使用 ==知识点== 1.可变参数 2.Stream流 ...

  3. java实体类和json串字段名称不一致或者与map中字段名称不一致使用注解转化

    package yuanCheng; import java.text.MessageFormat; import java.util.ArrayList; import java.util.List ...

  4. 数据接口请求异常:parsererror

    问题一:直接拿别人的文件放在本地打开 如下图 原因:这是提示"交叉源请求仅支持协议方案:HTTP.数据.Chrome.Chrome扩展.HTTPS." 也就是你不能用本地文件打开, ...

  5. SpringBoot全局时间转换器

    SpringBoot全局时间转换器 日常开发中,接收时间类型参数处处可见,但是针对不同的接口.往往需要的时间类型不一致 @DateTimeFormat(pattern = "yyyy-MM- ...

  6. Scriptable Render Pipeline

    Scriptable Render Pipeline SRP的核心是一堆API集合,使得整个渲染过程及相关配置暴露给用户,使得用户可以精确地控制项目的渲染流程. SRP API为原有的Unity构件提 ...

  7. @component的作用详细介绍

    最近项目要采用spring boot在学习的spring boot 的过程中第一次见到@component注解,特意在网上搜索下,摘录在此方便日后查阅. 1.@controller 控制器(注入服务) ...

  8. Oracle 模糊查询 优化

    模糊查询是数据库查询中经常用到的,一般常用的格式如下: (1)字段  like '%关键字%'   字段包含"关键字"的记录   即使在目标字段建立索引也不会走索引,速度最慢 (2 ...

  9. 认识webservice

    1.为什么需要webservice? 目前还有很多商用程序继续在使用C++.Java.Visual Basic和其他各种各样的语言编写.现在,除了最简单的程序之外,所有的应用程序都需要与运行在其他异构 ...

  10. 10步写了个Django网站,正经网站···

      Django做网站只要10步,真的只有10步,不信?咱们来数数--   今天主要讲解用Pycharm编辑器搭建网站,网站功能是 实现在局域网中快速传递大文件! 比如:同事要给你个1G的文件,你丢一 ...