Path: csiph.com!usenet.pasdenom.info!news.redatomik.org!newsfeed.xs4all.nl!newsfeed4.news.xs4all.nl!xs4all!newsgate.cistron.nl!newsgate.news.xs4all.nl!post.news.xs4all.nl!not-for-mail Return-Path: X-Original-To: python-list@python.org Delivered-To: python-list@mail.python.org X-Spam-Status: OK 0.005 X-Spam-Evidence: '*H*': 0.99; '*S*': 0.00; 'yet.': 0.04; 'lines,': 0.07; 'callback': 0.09; 'expected.': 0.09; 'section,': 0.09; 'things,': 0.09; 'wrapped': 0.09; 'wrong,': 0.09; '*why*': 0.16; ':-(': 0.16; 'all?': 0.16; 'coroutines': 0.16; 'frankly': 0.16; 'helps.': 0.16; 'occurs,': 0.16; 'placeholder': 0.16; 'subclass': 0.16; 'subject:between': 0.16; 'subject:tasks': 0.16; 'suspend': 0.16; 'tasks,': 0.16; 'wrote:': 0.18; 'things.': 0.19; 'fit': 0.20; 'seems': 0.21; 'paul': 0.24; 'looks': 0.24; "i've": 0.25; 'task': 0.26; 'header:In-Reply-To:1': 0.27; 'correct': 0.29; 'am,': 0.29; "doesn't": 0.30; 'message-id:@mail.gmail.com': 0.30; "i'm": 0.30; '(which': 0.31; 'lot.': 0.31; 'schedules': 0.31; 'yields': 0.31; 'allows': 0.31; 'themselves': 0.32; 'run': 0.32; 'says': 0.33; 'sense': 0.34; 'subject:the': 0.34; 'anywhere': 0.35; 'something': 0.35; 'objects': 0.35; 'but': 0.35; 'received:google.com': 0.35; 'described': 0.36; 'interaction': 0.36; 'done': 0.36; 'subject:?': 0.36; 'easily': 0.37; 'tasks': 0.38; 'to:addr:python-list': 0.38; 'rather': 0.38; 'to:addr:python.org': 0.39; 'called': 0.40; 'future': 0.60; 'event.': 0.60; 'is.': 0.60; 'hope': 0.61; 'back': 0.62; 'between': 0.67; 'completion': 0.78; 'hand': 0.80; 'future,': 0.83; '2015': 0.84; 'asynchronous': 0.84; 'scheduling': 0.84; 'task,': 0.91 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :content-type:content-transfer-encoding; bh=pyQydm+/vxS5kTljaSv9kew7GUJNWFACsycBH30QVZA=; b=YScsouZBmITfvPFgSNo73lWjV5+DKj3KvVQO3ipFMS62GtZjMxVN9P4blWh0wfAW57 xm0q04wf9B88aqzmUAr1N8P/1NCVCQycudvsZKv2qo3m1Qa4mvX2ckHZVo3qQTmE1+iW JhiLiw2plH6Y3KuG0qVRLz29/CR90+OdOIrHL5x+p4hOF8n7jF565gi3t4VNsiNnVWuN 0PZUK07FlEEa4LZzLRBQ6KGXVRcgfnb5HUZvfWes1WY+sO90HguCjL6pYQWaSnK8NJUd HTJUHEhcIH4pf9mo2pjJ1r45VfuVA8BR3uqEu2cqbLZ+1V0q60r7J5N271EysHRukvP2 OY4w== X-Received: by 10.107.12.158 with SMTP id 30mr20682194iom.61.1430848024797; Tue, 05 May 2015 10:47:04 -0700 (PDT) MIME-Version: 1.0 In-Reply-To: <344fd8f6-75c1-4b7d-888d-c5c9d4498ec3@googlegroups.com> References: <344fd8f6-75c1-4b7d-888d-c5c9d4498ec3@googlegroups.com> From: Ian Kelly Date: Tue, 5 May 2015 11:46:24 -0600 Subject: Re: asyncio: What is the difference between tasks, futures, and coroutines? To: Python Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable X-BeenThere: python-list@python.org X-Mailman-Version: 2.1.20+ Precedence: list List-Id: General discussion list for the Python programming language List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Newsgroups: comp.lang.python Message-ID: Lines: 49 NNTP-Posting-Host: 2001:888:2000:d::a6 X-Trace: 1430848034 news.xs4all.nl 2951 [2001:888:2000:d::a6]:59952 X-Complaints-To: abuse@xs4all.nl Xref: csiph.com comp.lang.python:89981 On Tue, May 5, 2015 at 9:22 AM, Paul Moore wrote: > I'm working my way through the asyncio documentation. I have got to the "= Tasks and coroutines" section, but I'm frankly confused as to the differenc= e between the various things described in that section: coroutines, tasks, = and futures. > > I think can understand a coroutine. Correct me if I'm wrong, but it's rou= ghly "something that you can run which can suspend itself". > > But I don't understand what a Future is. The document just says it's almo= st the same as a concurrent.futures.Future, which is described as something= that "encapsulates the asynchronous execution of a callable". Which doesn'= t help a lot. In concurrent.futures, you don't create Futures, you get them= back from submit(), but in the asyncio docs it looks like you can create t= hem by hand (example "Future with run_until_complete"). And there's nothing= that says what a Future is, just what it's like... :-( Fundamentally, a future is a placeholder for something that isn't available yet. You can use it to set a callback to be called when that thing is available, and once it's available you can get that thing from it. > A Task is a subclass of Future, but the documentation doesn't say what it= *is*, but rather that it "schedules the execution of a coroutine". But tha= t doesn't make sense to me - objects don't do things, they *are* things. I = thought the event loop did the scheduling? In asyncio, a Task is a a Future that serves as a placeholder for the result of a coroutine. The event loop manages callbacks, and that's all it does. An event that it's been told to listen for occurs, and the event loop calls the callback associated with that event. The Task manages a coroutine's interaction with the event loop; when the coroutine yields a future, the Task instructs the event loop to listen for the completion of that future, setting a callback that will resume the coroutine. > Reading between the lines, it seems that the event loop schedules Tasks (= which makes sense) and that Tasks somehow wrap up coroutines - but I don't = see *why* you need to wrap a task in a coroutine rather than just schedulin= g coroutines. And I don't see where Futures fit in - why not just wrap a co= routine in a Future, if it needs to be wrapped up at all? The coroutines themselves are not that interesting of an interface; all you can do with them is resume them. The asynchronous execution done by asyncio is all based on futures. Because a coroutine can easily be wrapped in a Task, this allows for coroutines to be used anywhere a future is expected. I don't know if I've done a good job explaining, but I hope this helps.