回答編集履歴

8

検証コードを変更

2021/06/15 12:18

投稿

teamikl
teamikl

スコア8664

test CHANGED
@@ -1,8 +1,8 @@
1
1
  - task3 の foo 内に await が無い為、main側でawait した時点でタスクが作成順に実行されている。
2
2
 
3
- - ~~bar() 関数は task4 を返すので~~ bar() は task4 を返すコルーチン
3
+ - ~~bar() 関数は task4 を返すので bar() は task4 を返すコルーチン~~
4
4
 
5
- task4 = await bar() の右辺を評価した時点で タスクは実行されてます。
5
+ ~~task4 = await bar() の右辺を評価した時点で タスクは実行されてます。~~
6
6
 
7
7
 
8
8
 
@@ -14,31 +14,33 @@
14
14
 
15
15
 
16
16
 
17
- 検証: 以降の `await task4` を追加したり削除しても結果は変わりません。
17
+ ~~検証: 以降の `await task4` を追加したり削除しても結果は変わりません。
18
18
 
19
- この時点の task4 は消化済みのタスクなので、何もしないで次の処理に移ります。
19
+ この時点の task4 は消化済みのタスクなので、何もしないで次の処理に移ります。~~
20
+
21
+
22
+
23
+
24
+
25
+ 訂正: タスクの実行を検証
20
26
 
21
27
  ```diff
22
28
 
23
29
  - await task4 # task4を実行.
24
30
 
25
- await task3 # task3を実行.
31
+ - await task3 # task3を実行.
32
+
33
+ + await asyncio.sleep(0) # task3, task4 が実行。await の右辺は何でもよい
34
+
35
+ # 実行コンテキストの切り替え、処理をイベントループに戻す
36
+
37
+ # → 実行可能なタスクが処理される
26
38
 
27
39
 
28
40
 
29
41
  ```
30
42
 
31
43
 
32
-
33
- ```diff
34
-
35
- + await task4 # task4を実行.
36
-
37
- await task4 # task4を実行.
38
-
39
- await task3 # task3を実行.
40
-
41
- ```
42
44
 
43
45
 
44
46
 
@@ -79,3 +81,11 @@
79
81
  foo,bar,baz のコルーチン内に await がない ということは、どれも 即実行可能なので、
80
82
 
81
83
  その為、await 順ではなく、実行順序は作成順になります。
84
+
85
+
86
+
87
+ ----
88
+
89
+ - create_task() で Task() が作成され、
90
+
91
+ - タスクはコンストラクタ内でイベントループにスケジュールされます。

7

質問に対する回答を追記

2021/06/15 12:18

投稿

teamikl
teamikl

スコア8664

test CHANGED
@@ -61,3 +61,21 @@
61
61
 
62
62
 
63
63
  ※ この場合、変数名に task は適切でないので、別名に。
64
+
65
+
66
+
67
+ ----
68
+
69
+ > どうしてtask3がtask4よりも先に実行されるのか。
70
+
71
+
72
+
73
+ タスクは、作成時に イベントループにスケジュールされ、
74
+
75
+ await でイベントループに処理が戻ったタイミングで、実行可能ならば実行されます。
76
+
77
+
78
+
79
+ foo,bar,baz のコルーチン内に await がない ということは、どれも 即実行可能なので、
80
+
81
+ その為、await 順ではなく、実行順序は作成順になります。

6

コードの整理

2021/06/15 11:10

投稿

teamikl
teamikl

スコア8664

test CHANGED
@@ -54,7 +54,7 @@
54
54
 
55
55
  - task3 = asyncio.create_task(foo("task3"))
56
56
 
57
- + task3 = foo("task3") # task3をクリエイト. PENDING.
57
+ + task3 = foo("task3")
58
58
 
59
59
  ```
60
60
 

5

想定する挙動を追記

2021/06/15 10:58

投稿

teamikl
teamikl

スコア8664

test CHANGED
@@ -39,3 +39,25 @@
39
39
  await task3 # task3を実行.
40
40
 
41
41
  ```
42
+
43
+
44
+
45
+ ----
46
+
47
+ 追記: 想定されている挙動 task3 を task4 後に遅らせたい場合は、
48
+
49
+ 恐らく、タスクではなくコルーチン
50
+
51
+
52
+
53
+ ```diff
54
+
55
+ - task3 = asyncio.create_task(foo("task3"))
56
+
57
+ + task3 = foo("task3") # task3をクリエイト. PENDING.
58
+
59
+ ```
60
+
61
+
62
+
63
+ ※ この場合、変数名に task は適切でないので、別名に。

4

説明が正確でなかったので訂正

2021/06/15 10:57

投稿

teamikl
teamikl

スコア8664

test CHANGED
@@ -1,8 +1,8 @@
1
1
  - task3 の foo 内に await が無い為、main側でawait した時点でタスクが作成順に実行されている。
2
2
 
3
- - bar() 関数は task4 を返すので
3
+ - ~~bar() 関数は task4 を返すので~~ bar() は task4 を返すコルーチン
4
4
 
5
- task4 = await bar() の右辺を評価した時点で task4 が実行されてます。
5
+ task4 = await bar() の右辺を評価した時点で タスクは実行されてます。
6
6
 
7
7
 
8
8
 

3

文章補足

2021/06/15 10:51

投稿

teamikl
teamikl

スコア8664

test CHANGED
@@ -1,4 +1,4 @@
1
- - task3 の foo 内に await が無い為、await 時点でタスクが作成順に実行されている。
1
+ - task3 の foo 内に await が無い為、main側でawait した時点でタスクが作成順に実行されている。
2
2
 
3
3
  - bar() 関数は task4 を返すので
4
4
 

2

もうひとつの問題点を追記

2021/06/15 10:37

投稿

teamikl
teamikl

スコア8664

test CHANGED
@@ -1,6 +1,6 @@
1
- 問題:
1
+ - task3 の foo 内に await が無い為、await の時でタスクが作成順に実行されている。
2
2
 
3
- bar() 関数は task4 を返すので
3
+ - bar() 関数は task4 を返すので
4
4
 
5
5
  task4 = await bar() の右辺を評価した時点で task4 が実行されてます。
6
6
 

1

訂正

2021/06/15 10:31

投稿

teamikl
teamikl

スコア8664

test CHANGED
@@ -39,21 +39,3 @@
39
39
  await task3 # task3を実行.
40
40
 
41
41
  ```
42
-
43
-
44
-
45
- ----
46
-
47
- 想定する順序の挙動にするには、bar() がそのまま task4 を返すようにします。
48
-
49
-
50
-
51
- ```diff
52
-
53
- - task4 = await bar()
54
-
55
- + task4 = bar()
56
-
57
-
58
-
59
- ```