-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathasyncio-dev.html
More file actions
497 lines (466 loc) · 54.5 KB
/
Copy pathasyncio-dev.html
File metadata and controls
497 lines (466 loc) · 54.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>18.5.9. asyncio での開発 — Python 3.6.5 ドキュメント</title>
<link rel="stylesheet" href="../_static/pydoctheme.css" type="text/css" />
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '../',
VERSION: '3.6.5',
COLLAPSE_INDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true,
SOURCELINK_SUFFIX: '.txt'
};
</script>
<script type="text/javascript" src="../_static/jquery.js"></script>
<script type="text/javascript" src="../_static/underscore.js"></script>
<script type="text/javascript" src="../_static/doctools.js"></script>
<script type="text/javascript" src="../_static/translations.js"></script>
<script type="text/javascript" src="../_static/sidebar.js"></script>
<link rel="search" type="application/opensearchdescription+xml"
title="Python 3.6.5 ドキュメント 内を検索"
href="../_static/opensearch.xml"/>
<link rel="author" title="このドキュメントについて" href="../about.html" />
<link rel="index" title="索引" href="../genindex.html" />
<link rel="search" title="検索" href="../search.html" />
<link rel="copyright" title="Copyright" href="../copyright.html" />
<link rel="next" title="18.6. asyncore — 非同期ソケットハンドラ" href="asyncore.html" />
<link rel="prev" title="18.5.8. キュー" href="asyncio-queue.html" />
<link rel="shortcut icon" type="image/png" href="../_static/py.png" />
<link rel="canonical" href="https://docs.python.jp/3/library/asyncio-dev.html" /><script type="text/javascript">
$(document).ready(function() {
var base = 'https://docs.python.org/3.6/library/asyncio-dev.html';
$('a.headerlink').each(function() {
var html = '<a href="' + base + $(this).attr('href') +
'" title="原文へのリンク"><small>(原文)</small></a>';
$(this).after(html);
})
});
</script>
<script type="text/javascript" src="../_static/copybutton.js"></script>
<script type="text/javascript" src="../_static/version_switch.js"></script>
</head>
<body>
<div class="related" role="navigation" aria-label="related navigation">
<h3>ナビゲーション</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../genindex.html" title="総索引"
accesskey="I">索引</a></li>
<li class="right" >
<a href="../py-modindex.html" title="Pythonモジュール索引"
>モジュール</a> |</li>
<li class="right" >
<a href="asyncore.html" title="18.6. asyncore — 非同期ソケットハンドラ"
accesskey="N">次へ</a> |</li>
<li class="right" >
<a href="asyncio-queue.html" title="18.5.8. キュー"
accesskey="P">前へ</a> |</li>
<li><img src="../_static/py.png" alt=""
style="vertical-align: middle; margin-top: -1px"/></li>
<li><a href="https://www.python.org/">Python</a> »</li>
<li>
<span class="version_switcher_placeholder">3.6.5</span>
<a href="../index.html">ドキュメント</a> »
</li>
<li class="nav-item nav-item-1"><a href="index.html" >Python 標準ライブラリ</a> »</li>
<li class="nav-item nav-item-2"><a href="ipc.html" >18. プロセス間通信とネットワーク</a> »</li>
<li class="nav-item nav-item-3"><a href="asyncio.html" accesskey="U">18.5. <code class="docutils literal"><span class="pre">asyncio</span></code> — 非同期 I/O、イベントループ、コルーチンおよびタスク</a> »</li>
<li class="right">
<div class="inline-search" style="display: none" role="search">
<form class="inline-search" action="../search.html" method="get">
<input placeholder="Quick search" type="text" name="q" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
<script type="text/javascript">$('.inline-search').show(0);</script>
|
</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<div class="section" id="develop-with-asyncio">
<span id="asyncio-dev"></span><h1>18.5.9. asyncio での開発<a class="headerlink" href="#develop-with-asyncio" title="このヘッドラインへのパーマリンク">¶</a></h1>
<p>非同期プログラミングは古典的な "逐次" プログラミングとは異なります。このページでは非同期プログラミングで陥りやすい落とし穴の一覧とその回避方法について説明しています。</p>
<div class="section" id="debug-mode-of-asyncio">
<span id="asyncio-debug-mode"></span><h2>18.5.9.1. asyncio のデバッグモード<a class="headerlink" href="#debug-mode-of-asyncio" title="このヘッドラインへのパーマリンク">¶</a></h2>
<p><a class="reference internal" href="asyncio.html#module-asyncio" title="asyncio: Asynchronous I/O, event loop, coroutines and tasks."><code class="xref py py-mod docutils literal"><span class="pre">asyncio</span></code></a> の実装では、パフォーマンスが重視されています。非同期コードの開発を行いやすくするには、 <em>デバッグモード</em> を有効にするとよいかもしれません。</p>
<p>アプリケーションで全てのデバッグチェックを有効にするには:</p>
<ul class="simple">
<li>環境変数 <span class="target" id="index-2"></span><a class="reference internal" href="../using/cmdline.html#envvar-PYTHONASYNCIODEBUG"><code class="xref std std-envvar docutils literal"><span class="pre">PYTHONASYNCIODEBUG</span></code></a> を <code class="docutils literal"><span class="pre">1</span></code> に設定するか、 <a class="reference internal" href="asyncio-eventloop.html#asyncio.AbstractEventLoop.set_debug" title="asyncio.AbstractEventLoop.set_debug"><code class="xref py py-meth docutils literal"><span class="pre">AbstractEventLoop.set_debug()</span></code></a> を呼び出すと、asyncio デバッグモードがグローバルに有効になります。</li>
<li><a class="reference internal" href="#asyncio-logger"><span class="std std-ref">asyncio logger</span></a> のトップレベルを <code class="xref py py-data docutils literal"><span class="pre">logging.DEBUG</span></code> に設定します。例えば、起動時に <code class="docutils literal"><span class="pre">logging.basicConfig(level=logging.DEBUG)</span></code> を呼び出します。</li>
<li><a class="reference internal" href="warnings.html#module-warnings" title="warnings: Issue warning messages and control their disposition."><code class="xref py py-mod docutils literal"><span class="pre">warnings</span></code></a> モジュールを構成して、 <a class="reference internal" href="exceptions.html#ResourceWarning" title="ResourceWarning"><code class="xref py py-exc docutils literal"><span class="pre">ResourceWarning</span></code></a> 警告が表示されるようにします。例えば、Python の <code class="docutils literal"><span class="pre">-Wdefault</span></code> コマンドラインオプションを使用して、それらを表示します。</li>
</ul>
<p>デバッグチェックの例:</p>
<ul class="simple">
<li><a class="reference internal" href="#asyncio-coroutine-not-scheduled"><span class="std std-ref">定義されているが "yielded from" されなかったコルーチン</span></a> のログを取ります</li>
<li>誤ったスレッドから呼ばれた場合、 <a class="reference internal" href="asyncio-eventloop.html#asyncio.AbstractEventLoop.call_soon" title="asyncio.AbstractEventLoop.call_soon"><code class="xref py py-meth docutils literal"><span class="pre">call_soon()</span></code></a> や <a class="reference internal" href="asyncio-eventloop.html#asyncio.AbstractEventLoop.call_at" title="asyncio.AbstractEventLoop.call_at"><code class="xref py py-meth docutils literal"><span class="pre">call_at()</span></code></a> メソッドが例外を送出します</li>
<li>セレクターの実行時間のログを取ります</li>
<li>実行時間が 100 ms を超えるコールバックのログ。<code class="xref py py-attr docutils literal"><span class="pre">AbstractEventLoop.slow_callback_duration</span></code> 属性には "遅い" コールバックとみなす最小時間を秒で指定できます。</li>
<li>トランスポートとイベントループが <a class="reference internal" href="#asyncio-close-transports"><span class="std std-ref">明示的に閉じられなかった</span></a> 場合、 <a class="reference internal" href="exceptions.html#ResourceWarning" title="ResourceWarning"><code class="xref py py-exc docutils literal"><span class="pre">ResourceWarning</span></code></a> 警告が出ます。</li>
</ul>
<div class="admonition seealso">
<p class="first admonition-title">参考</p>
<p class="last"><a class="reference internal" href="asyncio-eventloop.html#asyncio.AbstractEventLoop.set_debug" title="asyncio.AbstractEventLoop.set_debug"><code class="xref py py-meth docutils literal"><span class="pre">AbstractEventLoop.set_debug()</span></code></a> メソッドならびに <a class="reference internal" href="#asyncio-logger"><span class="std std-ref">asyncio logger</span></a>。</p>
</div>
</div>
<div class="section" id="cancellation">
<h2>18.5.9.2. 取り消し<a class="headerlink" href="#cancellation" title="このヘッドラインへのパーマリンク">¶</a></h2>
<p>古典的なプログラミングでは、タスクのキャンセルは一般的ではありません。非同期プログラミングでは、それは一般的であるどころか、それを処理するためのコードを用意する必要があります。</p>
<p>Future おびタスクは、それらの <a class="reference internal" href="asyncio-task.html#asyncio.Future.cancel" title="asyncio.Future.cancel"><code class="xref py py-meth docutils literal"><span class="pre">Future.cancel()</span></code></a> メソッドを呼び出すことで、明示的にキャンセルすることができます。<a class="reference internal" href="asyncio-task.html#asyncio.wait_for" title="asyncio.wait_for"><code class="xref py py-func docutils literal"><span class="pre">wait_for()</span></code></a> 関数は、タイムアウト発生時に、待機中のタスクをキャンセルします。タスクを間接的にキャンセルすることができる使用例は、他にも数多くあります。</p>
<p>Future がキャンセルされた場合、<a class="reference internal" href="asyncio-task.html#asyncio.Future" title="asyncio.Future"><code class="xref py py-class docutils literal"><span class="pre">Future</span></code></a> の <a class="reference internal" href="asyncio-task.html#asyncio.Future.set_result" title="asyncio.Future.set_result"><code class="xref py py-meth docutils literal"><span class="pre">set_result()</span></code></a> または <a class="reference internal" href="asyncio-task.html#asyncio.Future.set_exception" title="asyncio.Future.set_exception"><code class="xref py py-meth docutils literal"><span class="pre">set_exception()</span></code></a> メソッドは呼び出さないでください。例外を送出して、失敗してしまいます。例えば、以下のように書いてください。</p>
<div class="highlight-python3"><div class="highlight"><pre><span></span><span class="k">if</span> <span class="ow">not</span> <span class="n">fut</span><span class="o">.</span><span class="n">cancelled</span><span class="p">():</span>
<span class="n">fut</span><span class="o">.</span><span class="n">set_result</span><span class="p">(</span><span class="s1">'done'</span><span class="p">)</span>
</pre></div>
</div>
<p><a class="reference internal" href="asyncio-eventloop.html#asyncio.AbstractEventLoop.call_soon" title="asyncio.AbstractEventLoop.call_soon"><code class="xref py py-meth docutils literal"><span class="pre">AbstractEventLoop.call_soon()</span></code></a> で、Future の <a class="reference internal" href="asyncio-task.html#asyncio.Future.set_result" title="asyncio.Future.set_result"><code class="xref py py-meth docutils literal"><span class="pre">set_result()</span></code></a> メソッドまたは <a class="reference internal" href="asyncio-task.html#asyncio.Future.set_exception" title="asyncio.Future.set_exception"><code class="xref py py-meth docutils literal"><span class="pre">set_exception()</span></code></a> メソッドの呼び出しを直接スケジュールしないでください。Future は、そのメソッドが呼び出される前にキャンセルされる場合があります。</p>
<p>Future を待機する場合、Future がキャンセルされているかどうかを早い段階で確認し、無駄な操作を防いでください。以下に例を示します。</p>
<div class="highlight-python3"><div class="highlight"><pre><span></span><span class="nd">@coroutine</span>
<span class="k">def</span> <span class="nf">slow_operation</span><span class="p">(</span><span class="n">fut</span><span class="p">):</span>
<span class="k">if</span> <span class="n">fut</span><span class="o">.</span><span class="n">cancelled</span><span class="p">():</span>
<span class="k">return</span>
<span class="c1"># ... slow computation ...</span>
<span class="k">yield from</span> <span class="n">fut</span>
<span class="c1"># ...</span>
</pre></div>
</div>
<p><a class="reference internal" href="asyncio-task.html#asyncio.shield" title="asyncio.shield"><code class="xref py py-func docutils literal"><span class="pre">shield()</span></code></a> 関数も、キャンセルを無視するために使用できます。</p>
</div>
<div class="section" id="concurrency-and-multithreading">
<span id="asyncio-multithreading"></span><h2>18.5.9.3. 並行処理とマルチスレッド処理<a class="headerlink" href="#concurrency-and-multithreading" title="このヘッドラインへのパーマリンク">¶</a></h2>
<p>イベントループは 1 個のスレッド内で実行し、同じスレッド内ですべてのコールバックとタスクを実行します。1 個のタスクがイベントループ内で実行される間、他のタスクは同じスレッド内で実行されることはありません。ただし、タスクが <code class="docutils literal"><span class="pre">yield</span> <span class="pre">from</span></code> を使用するとそのタスクはサスペンドされ、イベントループは次のタスクを実行します。</p>
<p>異なるスレッドからコールバックをスケジュールする場合、 <a class="reference internal" href="asyncio-eventloop.html#asyncio.AbstractEventLoop.call_soon_threadsafe" title="asyncio.AbstractEventLoop.call_soon_threadsafe"><code class="xref py py-meth docutils literal"><span class="pre">AbstractEventLoop.call_soon_threadsafe()</span></code></a> メソッドを使用してください。例:</p>
<div class="highlight-python3"><div class="highlight"><pre><span></span><span class="n">loop</span><span class="o">.</span><span class="n">call_soon_threadsafe</span><span class="p">(</span><span class="n">callback</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">)</span>
</pre></div>
</div>
<p>ほとんどの asyncio オブジェクトはスレッドセーフではありません。イベントループの外からオブジェクトにアクセスしていないかどうかだけに注意してください。例えばフューチャーをキャンセルする場合にその <a class="reference internal" href="asyncio-task.html#asyncio.Future.cancel" title="asyncio.Future.cancel"><code class="xref py py-meth docutils literal"><span class="pre">Future.cancel()</span></code></a> メソッドを直接呼び出すのではなく以下のようにします:</p>
<div class="highlight-python3"><div class="highlight"><pre><span></span><span class="n">loop</span><span class="o">.</span><span class="n">call_soon_threadsafe</span><span class="p">(</span><span class="n">fut</span><span class="o">.</span><span class="n">cancel</span><span class="p">)</span>
</pre></div>
</div>
<p>シグナルの処理やサブプロセスの実行を行うには、イベントループはメインスレッド内で実行しなければなりません。</p>
<p>別のスレッドからコルーチンオブジェクトをスケジュールする場合は、 <a class="reference internal" href="asyncio-task.html#asyncio.run_coroutine_threadsafe" title="asyncio.run_coroutine_threadsafe"><code class="xref py py-func docutils literal"><span class="pre">run_coroutine_threadsafe()</span></code></a> メソッドを使用してください。
<a class="reference internal" href="asyncio-task.html#asyncio.run_coroutine_threadsafe" title="asyncio.run_coroutine_threadsafe"><code class="xref py py-func docutils literal"><span class="pre">run_coroutine_threadsafe()</span></code></a> は結果にアクセスするための <a class="reference internal" href="concurrent.futures.html#concurrent.futures.Future" title="concurrent.futures.Future"><code class="xref py py-class docutils literal"><span class="pre">concurrent.futures.Future</span></code></a> を返します:</p>
<div class="highlight-python3"><div class="highlight"><pre><span></span><span class="n">future</span> <span class="o">=</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">run_coroutine_threadsafe</span><span class="p">(</span><span class="n">coro_func</span><span class="p">(),</span> <span class="n">loop</span><span class="p">)</span>
<span class="n">result</span> <span class="o">=</span> <span class="n">future</span><span class="o">.</span><span class="n">result</span><span class="p">(</span><span class="n">timeout</span><span class="p">)</span> <span class="c1"># Wait for the result with a timeout</span>
</pre></div>
</div>
<p><a class="reference internal" href="asyncio-eventloop.html#asyncio.AbstractEventLoop.run_in_executor" title="asyncio.AbstractEventLoop.run_in_executor"><code class="xref py py-meth docutils literal"><span class="pre">AbstractEventLoop.run_in_executor()</span></code></a> メソッドをスレッドプール実行者とともに使用することで、イベントループのスレッドをブロックすることなく、別のスレッド内でコールバックを実行できます。</p>
<div class="admonition seealso">
<p class="first admonition-title">参考</p>
<p><a class="reference internal" href="asyncio-sync.html#asyncio-sync"><span class="std std-ref">同期プリミティブ</span></a> 節にはタスクの同期法が書かれています。</p>
<p class="last"><a class="reference internal" href="asyncio-subprocess.html#asyncio-subprocess-threads"><span class="std std-ref">サブプロセスとスレッド</span></a> 節では別スレッドからサブプロセスを実行する際の asyncio の限界を列挙しています。</p>
</div>
</div>
<div class="section" id="handle-blocking-functions-correctly">
<span id="asyncio-handle-blocking"></span><h2>18.5.9.4. ブロック関数を正しく扱う<a class="headerlink" href="#handle-blocking-functions-correctly" title="このヘッドラインへのパーマリンク">¶</a></h2>
<p>ブロック関数を直接呼び出してはなりません。例えば、関数が 1 秒間ブロックした場合、他のタスクには 1 秒間の遅延が発生します。これは反応性において重大な影響が発生します。</p>
<p>ネットワークとサブプロセスには、<a class="reference internal" href="asyncio.html#module-asyncio" title="asyncio: Asynchronous I/O, event loop, coroutines and tasks."><code class="xref py py-mod docutils literal"><span class="pre">asyncio</span></code></a> モジュールは <a class="reference internal" href="asyncio-protocol.html#asyncio-protocol"><span class="std std-ref">プロトコル</span></a> のような高水準 API を提供しています。</p>
<p>実行者を使用することで、イベントループのスレッドをブロックすることなく、別のスレッドや別のサブプロセスでタスクを実行できます。<a class="reference internal" href="asyncio-eventloop.html#asyncio.AbstractEventLoop.run_in_executor" title="asyncio.AbstractEventLoop.run_in_executor"><code class="xref py py-meth docutils literal"><span class="pre">AbstractEventLoop.run_in_executor()</span></code></a> メソッドを参照してください。</p>
<div class="admonition seealso">
<p class="first admonition-title">参考</p>
<p class="last"><a class="reference internal" href="asyncio-eventloop.html#asyncio-delayed-calls"><span class="std std-ref">遅延呼び出し</span></a> 節でイベントループで時間を扱う手順の詳細を説明しています。</p>
</div>
</div>
<div class="section" id="logging">
<span id="asyncio-logger"></span><h2>18.5.9.5. ログ記録<a class="headerlink" href="#logging" title="このヘッドラインへのパーマリンク">¶</a></h2>
<p><a class="reference internal" href="asyncio.html#module-asyncio" title="asyncio: Asynchronous I/O, event loop, coroutines and tasks."><code class="xref py py-mod docutils literal"><span class="pre">asyncio</span></code></a> モジュールは <a class="reference internal" href="logging.html#module-logging" title="logging: Flexible event logging system for applications."><code class="xref py py-mod docutils literal"><span class="pre">logging</span></code></a> モジュールとともにロガー <code class="docutils literal"><span class="pre">'asyncio'</span></code> の情報のログを記録します。</p>
<p><a class="reference internal" href="asyncio.html#module-asyncio" title="asyncio: Asynchronous I/O, event loop, coroutines and tasks."><code class="xref py py-mod docutils literal"><span class="pre">asyncio</span></code></a> モジュールのデフォルトのログレベルは、 <code class="xref py py-data docutils literal"><span class="pre">logging.INFO</span></code> です。<a class="reference internal" href="asyncio.html#module-asyncio" title="asyncio: Asynchronous I/O, event loop, coroutines and tasks."><code class="xref py py-mod docutils literal"><span class="pre">asyncio</span></code></a> にそれほどの冗長性を求めないユーザは、ログレベルを変更できます。例えば、レベルを <code class="xref py py-data docutils literal"><span class="pre">logging.WARNING</span></code> に変更するには、以下のようにします。</p>
<div class="highlight-none"><div class="highlight"><pre><span></span>logging.getLogger('asyncio').setLevel(logging.WARNING)
</pre></div>
</div>
</div>
<div class="section" id="detect-coroutine-objects-never-scheduled">
<span id="asyncio-coroutine-not-scheduled"></span><h2>18.5.9.6. スケジュールされなかったコルーチンオブジェクトの検出<a class="headerlink" href="#detect-coroutine-objects-never-scheduled" title="このヘッドラインへのパーマリンク">¶</a></h2>
<p>コルーチン関数が呼び出されてもその結果が <a class="reference internal" href="asyncio-task.html#asyncio.ensure_future" title="asyncio.ensure_future"><code class="xref py py-func docutils literal"><span class="pre">ensure_future()</span></code></a> や <a class="reference internal" href="asyncio-eventloop.html#asyncio.AbstractEventLoop.create_task" title="asyncio.AbstractEventLoop.create_task"><code class="xref py py-meth docutils literal"><span class="pre">AbstractEventLoop.create_task()</span></code></a> メソッドに渡されない場合、そのコルーチンオブジェクトの実行がスケジュールされることはなく、これはおそらくバグです。
<a class="reference internal" href="#asyncio-debug-mode"><span class="std std-ref">asyncio のデバッグモードの有効化</span></a> により <a class="reference internal" href="#asyncio-logger"><span class="std std-ref">警告のログ記録</span></a> を行うことでそれを検出できます。</p>
<p>バグの例:</p>
<div class="highlight-python3"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">asyncio</span>
<span class="nd">@asyncio</span><span class="o">.</span><span class="n">coroutine</span>
<span class="k">def</span> <span class="nf">test</span><span class="p">():</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"never scheduled"</span><span class="p">)</span>
<span class="n">test</span><span class="p">()</span>
</pre></div>
</div>
<p>デバッグモードの出力:</p>
<div class="highlight-python3"><div class="highlight"><pre><span></span><span class="n">Coroutine</span> <span class="n">test</span><span class="p">()</span> <span class="n">at</span> <span class="n">test</span><span class="o">.</span><span class="n">py</span><span class="p">:</span><span class="mi">3</span> <span class="n">was</span> <span class="n">never</span> <span class="n">yielded</span> <span class="kn">from</span>
<span class="nn">Coroutine</span> <span class="nb">object</span> <span class="n">created</span> <span class="n">at</span> <span class="p">(</span><span class="n">most</span> <span class="n">recent</span> <span class="n">call</span> <span class="n">last</span><span class="p">):</span>
<span class="n">File</span> <span class="s2">"test.py"</span><span class="p">,</span> <span class="n">line</span> <span class="mi">7</span><span class="p">,</span> <span class="ow">in</span> <span class="o"><</span><span class="n">module</span><span class="o">></span>
<span class="n">test</span><span class="p">()</span>
</pre></div>
</div>
<p>これを修正するには、そのコルーチンオブジェクトで <a class="reference internal" href="asyncio-task.html#asyncio.ensure_future" title="asyncio.ensure_future"><code class="xref py py-func docutils literal"><span class="pre">ensure_future()</span></code></a> 関数か <a class="reference internal" href="asyncio-eventloop.html#asyncio.AbstractEventLoop.create_task" title="asyncio.AbstractEventLoop.create_task"><code class="xref py py-meth docutils literal"><span class="pre">AbstractEventLoop.create_task()</span></code></a> メソッドを呼び出します。</p>
<div class="admonition seealso">
<p class="first admonition-title">参考</p>
<p class="last"><a class="reference internal" href="#asyncio-pending-task-destroyed"><span class="std std-ref">未完のタスクの破棄</span></a>。</p>
</div>
</div>
<div class="section" id="detect-exceptions-never-consumed">
<h2>18.5.9.7. 未処理の例外の検出<a class="headerlink" href="#detect-exceptions-never-consumed" title="このヘッドラインへのパーマリンク">¶</a></h2>
<p>Python は通常未処理の例外には <a class="reference internal" href="sys.html#sys.excepthook" title="sys.excepthook"><code class="xref py py-func docutils literal"><span class="pre">sys.excepthook()</span></code></a> を呼び出します。
<a class="reference internal" href="asyncio-task.html#asyncio.Future.set_exception" title="asyncio.Future.set_exception"><code class="xref py py-meth docutils literal"><span class="pre">Future.set_exception()</span></code></a> が呼び出されたものの処理されなかった場合、 <a class="reference internal" href="sys.html#sys.excepthook" title="sys.excepthook"><code class="xref py py-func docutils literal"><span class="pre">sys.excepthook()</span></code></a> が呼び出されません。
代わりに、フューチャーがガベージコレクションで削除されたとき、例外発生場所のトレースバックとともに <a class="reference internal" href="#asyncio-logger"><span class="std std-ref">ログが記録され</span></a> ます。</p>
<p>未処理の例外の例:</p>
<div class="highlight-python3"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">asyncio</span>
<span class="nd">@asyncio</span><span class="o">.</span><span class="n">coroutine</span>
<span class="k">def</span> <span class="nf">bug</span><span class="p">():</span>
<span class="k">raise</span> <span class="ne">Exception</span><span class="p">(</span><span class="s2">"not consumed"</span><span class="p">)</span>
<span class="n">loop</span> <span class="o">=</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">get_event_loop</span><span class="p">()</span>
<span class="n">asyncio</span><span class="o">.</span><span class="n">ensure_future</span><span class="p">(</span><span class="n">bug</span><span class="p">())</span>
<span class="n">loop</span><span class="o">.</span><span class="n">run_forever</span><span class="p">()</span>
<span class="n">loop</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
</pre></div>
</div>
<p>出力:</p>
<div class="highlight-python3"><div class="highlight"><pre><span></span><span class="n">Task</span> <span class="n">exception</span> <span class="n">was</span> <span class="n">never</span> <span class="n">retrieved</span>
<span class="n">future</span><span class="p">:</span> <span class="o"><</span><span class="n">Task</span> <span class="n">finished</span> <span class="n">coro</span><span class="o">=<</span><span class="n">coro</span><span class="p">()</span> <span class="n">done</span><span class="p">,</span> <span class="n">defined</span> <span class="n">at</span> <span class="n">asyncio</span><span class="o">/</span><span class="n">coroutines</span><span class="o">.</span><span class="n">py</span><span class="p">:</span><span class="mi">139</span><span class="o">></span> <span class="n">exception</span><span class="o">=</span><span class="ne">Exception</span><span class="p">(</span><span class="s1">'not consumed'</span><span class="p">,)</span><span class="o">></span>
<span class="n">Traceback</span> <span class="p">(</span><span class="n">most</span> <span class="n">recent</span> <span class="n">call</span> <span class="n">last</span><span class="p">):</span>
<span class="n">File</span> <span class="s2">"asyncio/tasks.py"</span><span class="p">,</span> <span class="n">line</span> <span class="mi">237</span><span class="p">,</span> <span class="ow">in</span> <span class="n">_step</span>
<span class="n">result</span> <span class="o">=</span> <span class="nb">next</span><span class="p">(</span><span class="n">coro</span><span class="p">)</span>
<span class="n">File</span> <span class="s2">"asyncio/coroutines.py"</span><span class="p">,</span> <span class="n">line</span> <span class="mi">141</span><span class="p">,</span> <span class="ow">in</span> <span class="n">coro</span>
<span class="n">res</span> <span class="o">=</span> <span class="n">func</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kw</span><span class="p">)</span>
<span class="n">File</span> <span class="s2">"test.py"</span><span class="p">,</span> <span class="n">line</span> <span class="mi">5</span><span class="p">,</span> <span class="ow">in</span> <span class="n">bug</span>
<span class="k">raise</span> <span class="ne">Exception</span><span class="p">(</span><span class="s2">"not consumed"</span><span class="p">)</span>
<span class="ne">Exception</span><span class="p">:</span> <span class="ow">not</span> <span class="n">consumed</span>
</pre></div>
</div>
<p><a class="reference internal" href="#asyncio-debug-mode"><span class="std std-ref">asyncio のデバッグモードの有効化</span></a> によりタスクが生成したトレースバックを取得できます。デバッグモードの出力は以下のようになります:</p>
<div class="highlight-python3"><div class="highlight"><pre><span></span><span class="n">Task</span> <span class="n">exception</span> <span class="n">was</span> <span class="n">never</span> <span class="n">retrieved</span>
<span class="n">future</span><span class="p">:</span> <span class="o"><</span><span class="n">Task</span> <span class="n">finished</span> <span class="n">coro</span><span class="o">=<</span><span class="n">bug</span><span class="p">()</span> <span class="n">done</span><span class="p">,</span> <span class="n">defined</span> <span class="n">at</span> <span class="n">test</span><span class="o">.</span><span class="n">py</span><span class="p">:</span><span class="mi">3</span><span class="o">></span> <span class="n">exception</span><span class="o">=</span><span class="ne">Exception</span><span class="p">(</span><span class="s1">'not consumed'</span><span class="p">,)</span> <span class="n">created</span> <span class="n">at</span> <span class="n">test</span><span class="o">.</span><span class="n">py</span><span class="p">:</span><span class="mi">8</span><span class="o">></span>
<span class="n">source_traceback</span><span class="p">:</span> <span class="n">Object</span> <span class="n">created</span> <span class="n">at</span> <span class="p">(</span><span class="n">most</span> <span class="n">recent</span> <span class="n">call</span> <span class="n">last</span><span class="p">):</span>
<span class="n">File</span> <span class="s2">"test.py"</span><span class="p">,</span> <span class="n">line</span> <span class="mi">8</span><span class="p">,</span> <span class="ow">in</span> <span class="o"><</span><span class="n">module</span><span class="o">></span>
<span class="n">asyncio</span><span class="o">.</span><span class="n">ensure_future</span><span class="p">(</span><span class="n">bug</span><span class="p">())</span>
<span class="n">Traceback</span> <span class="p">(</span><span class="n">most</span> <span class="n">recent</span> <span class="n">call</span> <span class="n">last</span><span class="p">):</span>
<span class="n">File</span> <span class="s2">"asyncio/tasks.py"</span><span class="p">,</span> <span class="n">line</span> <span class="mi">237</span><span class="p">,</span> <span class="ow">in</span> <span class="n">_step</span>
<span class="n">result</span> <span class="o">=</span> <span class="nb">next</span><span class="p">(</span><span class="n">coro</span><span class="p">)</span>
<span class="n">File</span> <span class="s2">"asyncio/coroutines.py"</span><span class="p">,</span> <span class="n">line</span> <span class="mi">79</span><span class="p">,</span> <span class="ow">in</span> <span class="fm">__next__</span>
<span class="k">return</span> <span class="nb">next</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">gen</span><span class="p">)</span>
<span class="n">File</span> <span class="s2">"asyncio/coroutines.py"</span><span class="p">,</span> <span class="n">line</span> <span class="mi">141</span><span class="p">,</span> <span class="ow">in</span> <span class="n">coro</span>
<span class="n">res</span> <span class="o">=</span> <span class="n">func</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kw</span><span class="p">)</span>
<span class="n">File</span> <span class="s2">"test.py"</span><span class="p">,</span> <span class="n">line</span> <span class="mi">5</span><span class="p">,</span> <span class="ow">in</span> <span class="n">bug</span>
<span class="k">raise</span> <span class="ne">Exception</span><span class="p">(</span><span class="s2">"not consumed"</span><span class="p">)</span>
<span class="ne">Exception</span><span class="p">:</span> <span class="ow">not</span> <span class="n">consumed</span>
</pre></div>
</div>
<p>この問題を解決するには異なるオプションがあります。最初のオプションでは、別のコルーチン内でコルーチンをチェーンし、古典的な try/except を使用します:</p>
<div class="highlight-python3"><div class="highlight"><pre><span></span><span class="nd">@asyncio</span><span class="o">.</span><span class="n">coroutine</span>
<span class="k">def</span> <span class="nf">handle_exception</span><span class="p">():</span>
<span class="k">try</span><span class="p">:</span>
<span class="k">yield from</span> <span class="n">bug</span><span class="p">()</span>
<span class="k">except</span> <span class="ne">Exception</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"exception consumed"</span><span class="p">)</span>
<span class="n">loop</span> <span class="o">=</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">get_event_loop</span><span class="p">()</span>
<span class="n">asyncio</span><span class="o">.</span><span class="n">ensure_future</span><span class="p">(</span><span class="n">handle_exception</span><span class="p">())</span>
<span class="n">loop</span><span class="o">.</span><span class="n">run_forever</span><span class="p">()</span>
<span class="n">loop</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
</pre></div>
</div>
<p><a class="reference internal" href="asyncio-eventloop.html#asyncio.AbstractEventLoop.run_until_complete" title="asyncio.AbstractEventLoop.run_until_complete"><code class="xref py py-meth docutils literal"><span class="pre">AbstractEventLoop.run_until_complete()</span></code></a> 関数を使う別のオプション:</p>
<div class="highlight-python3"><div class="highlight"><pre><span></span><span class="n">task</span> <span class="o">=</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">ensure_future</span><span class="p">(</span><span class="n">bug</span><span class="p">())</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">loop</span><span class="o">.</span><span class="n">run_until_complete</span><span class="p">(</span><span class="n">task</span><span class="p">)</span>
<span class="k">except</span> <span class="ne">Exception</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"exception consumed"</span><span class="p">)</span>
</pre></div>
</div>
<div class="admonition seealso">
<p class="first admonition-title">参考</p>
<p class="last"><a class="reference internal" href="asyncio-task.html#asyncio.Future.exception" title="asyncio.Future.exception"><code class="xref py py-meth docutils literal"><span class="pre">Future.exception()</span></code></a> メソッド。</p>
</div>
</div>
<div class="section" id="chain-coroutines-correctly">
<h2>18.5.9.8. コルーチンを正しくチェーンする<a class="headerlink" href="#chain-coroutines-correctly" title="このヘッドラインへのパーマリンク">¶</a></h2>
<p>コルーチン関数が別のコルーチン関数かタスクを呼び出すとき、それらは <code class="docutils literal"><span class="pre">yield</span> <span class="pre">from</span></code> で明示的にチェーンされなければなりません。そうされなかった場合、逐次的に実行されることは保証されません。</p>
<p><a class="reference internal" href="asyncio-task.html#asyncio.sleep" title="asyncio.sleep"><code class="xref py py-func docutils literal"><span class="pre">asyncio.sleep()</span></code></a> を使って処理速度の低下をシミュレートする異なるバグの例:</p>
<div class="highlight-python3"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">asyncio</span>
<span class="nd">@asyncio</span><span class="o">.</span><span class="n">coroutine</span>
<span class="k">def</span> <span class="nf">create</span><span class="p">():</span>
<span class="k">yield from</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="mf">3.0</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"(1) create file"</span><span class="p">)</span>
<span class="nd">@asyncio</span><span class="o">.</span><span class="n">coroutine</span>
<span class="k">def</span> <span class="nf">write</span><span class="p">():</span>
<span class="k">yield from</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="mf">1.0</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"(2) write into file"</span><span class="p">)</span>
<span class="nd">@asyncio</span><span class="o">.</span><span class="n">coroutine</span>
<span class="k">def</span> <span class="nf">close</span><span class="p">():</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"(3) close file"</span><span class="p">)</span>
<span class="nd">@asyncio</span><span class="o">.</span><span class="n">coroutine</span>
<span class="k">def</span> <span class="nf">test</span><span class="p">():</span>
<span class="n">asyncio</span><span class="o">.</span><span class="n">ensure_future</span><span class="p">(</span><span class="n">create</span><span class="p">())</span>
<span class="n">asyncio</span><span class="o">.</span><span class="n">ensure_future</span><span class="p">(</span><span class="n">write</span><span class="p">())</span>
<span class="n">asyncio</span><span class="o">.</span><span class="n">ensure_future</span><span class="p">(</span><span class="n">close</span><span class="p">())</span>
<span class="k">yield from</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="mf">2.0</span><span class="p">)</span>
<span class="n">loop</span><span class="o">.</span><span class="n">stop</span><span class="p">()</span>
<span class="n">loop</span> <span class="o">=</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">get_event_loop</span><span class="p">()</span>
<span class="n">asyncio</span><span class="o">.</span><span class="n">ensure_future</span><span class="p">(</span><span class="n">test</span><span class="p">())</span>
<span class="n">loop</span><span class="o">.</span><span class="n">run_forever</span><span class="p">()</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"Pending tasks at exit: </span><span class="si">%s</span><span class="s2">"</span> <span class="o">%</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">Task</span><span class="o">.</span><span class="n">all_tasks</span><span class="p">(</span><span class="n">loop</span><span class="p">))</span>
<span class="n">loop</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
</pre></div>
</div>
<p>予想される出力:</p>
<div class="highlight-none"><div class="highlight"><pre><span></span>(1) create file
(2) write into file
(3) close file
Pending tasks at exit: set()
</pre></div>
</div>
<p>実際の出力:</p>
<div class="highlight-none"><div class="highlight"><pre><span></span>(3) close file
(2) write into file
Pending tasks at exit: {<Task pending create() at test.py:7 wait_for=<Future pending cb=[Task._wakeup()]>>}
Task was destroyed but it is pending!
task: <Task pending create() done at test.py:5 wait_for=<Future pending cb=[Task._wakeup()]>>
</pre></div>
</div>
<p><code class="docutils literal"><span class="pre">create()</span></code> が完了する前か、<code class="docutils literal"><span class="pre">write()</span></code> を呼び出す前に <code class="docutils literal"><span class="pre">close()</span></code> が呼び出されたか、その一方でコルーチン関数が <code class="docutils literal"><span class="pre">create()</span></code>、<code class="docutils literal"><span class="pre">write()</span></code>。<code class="docutils literal"><span class="pre">close()</span></code> の順で呼び出された場合、ループは停止します。</p>
<p>この問題を解決するには、タスクは <code class="docutils literal"><span class="pre">yield</span> <span class="pre">from</span></code> でマークされなければなりません:</p>
<div class="highlight-python3"><div class="highlight"><pre><span></span><span class="nd">@asyncio</span><span class="o">.</span><span class="n">coroutine</span>
<span class="k">def</span> <span class="nf">test</span><span class="p">():</span>
<span class="k">yield from</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">ensure_future</span><span class="p">(</span><span class="n">create</span><span class="p">())</span>
<span class="k">yield from</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">ensure_future</span><span class="p">(</span><span class="n">write</span><span class="p">())</span>
<span class="k">yield from</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">ensure_future</span><span class="p">(</span><span class="n">close</span><span class="p">())</span>
<span class="k">yield from</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="mf">2.0</span><span class="p">)</span>
<span class="n">loop</span><span class="o">.</span><span class="n">stop</span><span class="p">()</span>
</pre></div>
</div>
<p>あるいは、<code class="docutils literal"><span class="pre">asyncio.ensure_future()</span></code> を使いません:</p>
<div class="highlight-python3"><div class="highlight"><pre><span></span><span class="nd">@asyncio</span><span class="o">.</span><span class="n">coroutine</span>
<span class="k">def</span> <span class="nf">test</span><span class="p">():</span>
<span class="k">yield from</span> <span class="n">create</span><span class="p">()</span>
<span class="k">yield from</span> <span class="n">write</span><span class="p">()</span>
<span class="k">yield from</span> <span class="n">close</span><span class="p">()</span>
<span class="k">yield from</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="mf">2.0</span><span class="p">)</span>
<span class="n">loop</span><span class="o">.</span><span class="n">stop</span><span class="p">()</span>
</pre></div>
</div>
</div>
<div class="section" id="pending-task-destroyed">
<span id="asyncio-pending-task-destroyed"></span><h2>18.5.9.9. 未完のタスクの破棄<a class="headerlink" href="#pending-task-destroyed" title="このヘッドラインへのパーマリンク">¶</a></h2>
<p>未完のタスクが破棄された場合、それがラップした <a class="reference internal" href="asyncio-task.html#coroutine"><span class="std std-ref">コルーチン</span></a> は完了しません。これがおそらくバグであり、そのため警告がログに記録されます。</p>
<p>ログの例:</p>
<div class="highlight-none"><div class="highlight"><pre><span></span>Task was destroyed but it is pending!
task: <Task pending coro=<kill_me() done, defined at test.py:5> wait_for=<Future pending cb=[Task._wakeup()]>>
</pre></div>
</div>
<p><a class="reference internal" href="#asyncio-debug-mode"><span class="std std-ref">asyncio のデバッグモードの有効化</span></a> をすることで、タスクが生成された場所でトレースバックを取得できます。以下はデバッグモードでログを記録する例です。</p>
<div class="highlight-none"><div class="highlight"><pre><span></span>Task was destroyed but it is pending!
source_traceback: Object created at (most recent call last):
File "test.py", line 15, in <module>
task = asyncio.ensure_future(coro, loop=loop)
task: <Task pending coro=<kill_me() done, defined at test.py:5> wait_for=<Future pending cb=[Task._wakeup()] created at test.py:7> created at test.py:15>
</pre></div>
</div>
<div class="admonition seealso">
<p class="first admonition-title">参考</p>
<p class="last"><a class="reference internal" href="#asyncio-coroutine-not-scheduled"><span class="std std-ref">スケジュールされなかったコルーチンオブジェクトの検出</span></a>。</p>
</div>
</div>
<div class="section" id="close-transports-and-event-loops">
<span id="asyncio-close-transports"></span><h2>18.5.9.10. トランスポートとイベントループを閉じる<a class="headerlink" href="#close-transports-and-event-loops" title="このヘッドラインへのパーマリンク">¶</a></h2>
<p>もはやトランスポートの必要がない場合、その <code class="docutils literal"><span class="pre">close()</span></code> メソッドを呼び出して、リソースを解放します。イベントループも、明示的に閉じなければなりません。</p>
<p>トランスポートまたはイベントループが明示的に閉じられない場合、デストラクタ内で <a class="reference internal" href="exceptions.html#ResourceWarning" title="ResourceWarning"><code class="xref py py-exc docutils literal"><span class="pre">ResourceWarning</span></code></a> 警告が送出されます。デフォルトでは、 <a class="reference internal" href="exceptions.html#ResourceWarning" title="ResourceWarning"><code class="xref py py-exc docutils literal"><span class="pre">ResourceWarning</span></code></a> 警告は無視されます。<a class="reference internal" href="#asyncio-debug-mode"><span class="std std-ref">asyncio のデバッグモード</span></a> セクションで、それらを表示する方法を説明します。</p>
</div>
</div>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<h3><a href="../contents.html">目次</a></h3>
<ul>
<li><a class="reference internal" href="#">18.5.9. asyncio での開発</a><ul>
<li><a class="reference internal" href="#debug-mode-of-asyncio">18.5.9.1. asyncio のデバッグモード</a></li>
<li><a class="reference internal" href="#cancellation">18.5.9.2. 取り消し</a></li>
<li><a class="reference internal" href="#concurrency-and-multithreading">18.5.9.3. 並行処理とマルチスレッド処理</a></li>
<li><a class="reference internal" href="#handle-blocking-functions-correctly">18.5.9.4. ブロック関数を正しく扱う</a></li>
<li><a class="reference internal" href="#logging">18.5.9.5. ログ記録</a></li>
<li><a class="reference internal" href="#detect-coroutine-objects-never-scheduled">18.5.9.6. スケジュールされなかったコルーチンオブジェクトの検出</a></li>
<li><a class="reference internal" href="#detect-exceptions-never-consumed">18.5.9.7. 未処理の例外の検出</a></li>
<li><a class="reference internal" href="#chain-coroutines-correctly">18.5.9.8. コルーチンを正しくチェーンする</a></li>
<li><a class="reference internal" href="#pending-task-destroyed">18.5.9.9. 未完のタスクの破棄</a></li>
<li><a class="reference internal" href="#close-transports-and-event-loops">18.5.9.10. トランスポートとイベントループを閉じる</a></li>
</ul>
</li>
</ul>
<h4>前のトピックへ</h4>
<p class="topless"><a href="asyncio-queue.html"
title="前の章へ">18.5.8. キュー</a></p>
<h4>次のトピックへ</h4>
<p class="topless"><a href="asyncore.html"
title="次の章へ">18.6. <code class="docutils literal"><span class="pre">asyncore</span></code> — 非同期ソケットハンドラ</a></p>
<div role="note" aria-label="source link">
<h3>このページ</h3>
<ul class="this-page-menu">
<li><a href="../bugs.html">バグ報告</a></li>
<li>
<a href="https://github.com/python/cpython/blob/3.6/Doc/library/asyncio-dev.rst"
rel="nofollow">ソースの表示
</a>
</li>
</ul>
</div>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related" role="navigation" aria-label="related navigation">
<h3>ナビゲーション</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../genindex.html" title="総索引"
>索引</a></li>
<li class="right" >
<a href="../py-modindex.html" title="Pythonモジュール索引"
>モジュール</a> |</li>
<li class="right" >
<a href="asyncore.html" title="18.6. asyncore — 非同期ソケットハンドラ"
>次へ</a> |</li>
<li class="right" >
<a href="asyncio-queue.html" title="18.5.8. キュー"
>前へ</a> |</li>
<li><img src="../_static/py.png" alt=""
style="vertical-align: middle; margin-top: -1px"/></li>
<li><a href="https://www.python.org/">Python</a> »</li>
<li>
<span class="version_switcher_placeholder">3.6.5</span>
<a href="../index.html">ドキュメント</a> »
</li>
<li class="nav-item nav-item-1"><a href="index.html" >Python 標準ライブラリ</a> »</li>
<li class="nav-item nav-item-2"><a href="ipc.html" >18. プロセス間通信とネットワーク</a> »</li>
<li class="nav-item nav-item-3"><a href="asyncio.html" >18.5. <code class="docutils literal"><span class="pre">asyncio</span></code> — 非同期 I/O、イベントループ、コルーチンおよびタスク</a> »</li>
<li class="right">
<div class="inline-search" style="display: none" role="search">
<form class="inline-search" action="../search.html" method="get">
<input placeholder="Quick search" type="text" name="q" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
<script type="text/javascript">$('.inline-search').show(0);</script>
|
</li>
</ul>
</div>
<div class="footer">
© <a href="../copyright.html">Copyright</a> 2001-2018, Python Software Foundation.
<br />
Python Software Foundation は非営利団体です。
<a href="https://www.python.org/psf/donations/">寄付</a>
<br />
最終更新日時: 7月 29, 2018
<a href="../bugs.html">バグを見つけたら</a>?
<br />
このドキュメントは <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.6.5 を使って作成されました。
</div>
</body>
</html>