asyncio和trio之间的核心区别是什么? [英] What is the core difference between asyncio and trio?

查看:171
本文介绍了asyncio和trio之间的核心区别是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

今天,我发现了一个名为 trio 的库,它说自己是异步的适用于人类的API.这些词与requests'有点类似.由于requests确实是一个很好的库,所以我想知道trio的优点是什么.

关于它的文章不多,我只是找到一个解决方案

我来自哪里:我是trio的主要作者.我还是curio的主要贡献者之一(并撰写了您链接到该文章的文章),并且是一名Python核心开发人员,他一直积极参与有关如何改进asyncio的讨论.

我不确定您对回调的含义.在trio(和curio)中,核心设计原则之一是永远不要使用回调进行编程.与基于回调的编程相比,它更像是基于线程的编程.我猜想,如果您打开引擎盖,看看它们是如何在内部实现的,那么在某些地方,它们会使用回调,或者如果您斜视,它们在某种程度上等效于回调.但这就像说Python和C是等效的,因为Python解释器是用C实现的.从不使用回调.

无论如何:

Trio vs asyncio

Asyncio更成熟

第一个大差异是生态系统的成熟度.当我在 2018年3月撰写本文时,与异步支持相比,支持异步的库多了[em> 个.例如,目前还没有任何真正的具有三重奏支持的HTTP服务器. PyPI上的 Framework :: AsyncIO分类器当前具有122个库,而 Framework :: Trio分类器只有8.我希望答案的这一部分会很快过时–例如,这里是肯尼思·雷兹(Kenneth Reitz)尝试添加三重奏在下一版本的请求中提供支持 –但是现在,您应该期望,如果您对复杂的事情感到三重,那么您将遇到需要自己填写的缺失部分,而不是从中获取库pypi,或者您需要使用 trio-asyncio软件包,该软件包可让您在三重奏程序中使用asyncio库. (三重聊天频道对于了解可用内容以及其他人正在从事的工作很有用. )

Trio使您的代码更简单

就实际的库而言,它们也有很大的不同. trio的主要论点是,与使用asyncio相比,它使编写并发代码更加简单.当然,当您最后一次听到有人说他们的图书馆使事情变得更难使用时,...让我举一个具体的例子.在此演讲(,这是一种用于有效建立网络连接的简单并发算法.这是 Glyph 多年来一直在思考的问题,而他最新的Twisted版本大约有600行. (Asyncio大致相同; Twisted和asyncio在架构上非常相似.)在演讲中,我教给您使用Trio在少于40行中实现它所需的一切知识(并且我们在修复他的版本中的一个错误时,在).因此,在此示例中,从字面上使用trio可使我们的代码简化一个数量级.

您可能还会发现来自用户的以下评论很有趣: 1 2

Trio的超时和取消管理方式很新颖,我认为比以前的最新系统(例如C#和Golang)要好. 我实际上确实写了整篇文章,所以我不会不要在这里详细介绍所有细节.但是asyncio的取消系统(或者说,实际上,它具有两个语义稍有不同的系统)基于一套比C#和Golang更旧的思想,并且很难正确使用. (例如,代码很容易通过生成后台任务意外地逃避"取消;请参见上一段.)

asyncio中有很多冗余的 stuff 很难做到告诉何时使用哪个东西.您拥有期货,任务和协程,它们基本上都用于相同的目的,但是您需要了解它们之间的区别.如果要实现网络协议,则必须选择是使用协议/传输层还是流层,它们都具有棘手的陷阱(这是 urllib .)可以在asyncio中添加三重奏中的多少个新想法?没人知道.我希望今年在PyCon上会有很多有趣的讨论:-).

Today, I found a library named trio which says itself is an asynchronous API for humans. These words are a little similar with requests'. As requests is really a good library, I am wondering what is the advantages of trio.

There aren't many articles about it, I just find an article discussing curio and asyncio. To my surprise, trio says itself is even better than curio(next-generation curio).

After reading half of the article, I cannot find the core difference between these two asynchronous framework. It just gives some examples that curio's implementation is more convenient than asyncio's. But the underlying structure is almost the same(callback-based, I think all asynchronous IO framework are based on callback without any exception.)

So could someone give me a reason I have to accept that trio or curio is better than asyncio? Or explain more about why I should choose trio instead of built-in asyncio?

解决方案

Where I'm coming from: I'm the primary author of trio. I'm also one of the top contributors to curio (and wrote the article about it that you link to), and a Python core dev who's been heavily involved in discussions about how to improve asyncio.

I'm not sure what you mean about callbacks. In trio (and curio), one of the core design principles is that you never program with callbacks; it feels more like thread-based programming than callback-based programming. I guess if you open up the hood and look at how they're implemented internally, then there are places where they use callbacks, or things that are sorta equivalent to callbacks if you squint. But that's like saying that Python and C are equivalent because the Python interpreter is implemented in C. You never use callbacks.

Anyway:

Trio vs asyncio

Asyncio is more mature

The first big difference is ecosystem maturity. At the time I'm writing this in March 2018, there are many more libraries with asyncio support than trio support. For example, right now there aren't any real HTTP servers with trio support. The Framework :: AsyncIO classifier on PyPI currently has 122 libraries in it, while the Framework :: Trio classifier only has 8. I'm hoping that this part of the answer will become out of date quickly – for example, here's Kenneth Reitz experimenting with adding trio support in the next version of requests – but right now, you should expect that if you're trio for anything complicated, then you'll run into missing pieces that you need to fill in yourself instead of grabbing a library from pypi, or that you'll need to use the trio-asyncio package that lets you use asyncio libraries in trio programs. (The trio chat channel is useful for finding out about what's available, and what other people are working on.)

Trio makes your code simpler

In terms of the actual libraries, they're also very different. The main argument for trio is that it makes writing concurrent code much, much simpler than using asyncio. Of course, when was the last time you heard someone say that their library makes things harder to use... let me give a concrete example. In this talk (slides), I use the example of implementing RFC 8305 "Happy eyeballs", which is a simple concurrent algorithm used to efficiently establish a network connection. This is something that Glyph has been thinking about for years, and his latest version for Twisted is ~600 lines long. (Asyncio would be about the same; Twisted and asyncio are very similar architecturally.) In the talk, I teach you everything you need to know to implement it in <40 lines using trio (and we fix a bug in his version while we're at it). So in this example, using trio literally makes our code an order of magnitude simpler.

You might also find these comments from users interesting: 1, 2, 3

There are many many differences in detail

Why does this happen? That's a much longer answer :-). I'm gradually working on writing up the different pieces in blog posts and talks, and I'll try to remember to update this answer with links as they become available. Basically, it comes down to Trio having a small set of carefully designed primitives that have a few fundamental differences from any other library I know of (though of course build on ideas from lots of places). Here are some random notes to give you some idea:

A very, very common problem in asyncio and related libraries is that you call some_function(), and it returns, so you think it's done – but actually it's still running in the background. This leads to all kinds of tricky bugs, because it makes it difficult to control the order in which things happen, or know when anything has actually finished, and it can directly hide problems because if a background task crashes with an unhandled exception, asyncio will generally just print something to the console and then keep going. In trio, the way we handle task spawning via "nurseries" means that none of these things happen: when a function returns then you know it's done, and Trio's currently the only concurrency library for Python where exceptions always propagate until you catch them.

Trio's way of managing timeouts and cancellations is novel, and I think better than previous state-of-the-art systems like C# and Golang. I actually did write a whole essay on this, so I won't go into all the details here. But asyncio's cancellation system – or really, systems, it has two of them with slightly different semantics – are based on an older set of ideas than even C# and Golang, and are difficult to use correctly. (For example, it's easy for code to accidentally "escape" a cancellation by spawning a background task; see previous paragraph.)

There's a ton of redundant stuff in asyncio, which can make it hard to tell which thing to use when. You have futures, tasks, and coroutines, which are all basically used for the same purpose but you need to know the differences between them. If you want to implement a network protocol, you have to pick whether to use the protocols/transports layer or the streams layer, and they both have tricky pitfalls (this is what the first part of the essay you linked is about).

Trio's currently the only concurrency library for Python where control-C just works the way you expect (i.e., it raises KeyboardInterrupt where-ever your code is). It's a small thing, but it makes a big difference :-). For various reasons, I don't think this is fixable in asyncio.

Summing up

If you need to ship something to production next week, then you should use asyncio (or Twisted or Tornado or gevent, which are even more mature). They have large ecosystems, other people have used them in production before you, and they're not going anywhere.

If trying to use those frameworks leaves you frustrated and confused, or if want to experiment with a different way of doing things, then definitely check out trio – we're friendly :-).

If you want to ship something to production a year from now... then I'm not sure what to tell you. Python concurrency is in flux. Trio has many advantages at the design level, but is that enough to overcome asyncio's head start? Will asyncio being in the standard library be an advantage, or a disadvantage? (Notice how these days everyone uses requests, even though the standard library has urllib.) How many of the new ideas in trio can be added to asyncio? No-one knows. I expect that there will be a lot of interesting discussions about this at PyCon this year :-).

这篇关于asyncio和trio之间的核心区别是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆