回答編集履歴

3

修正: 語弊がある表現だったのを修正

2021/06/27 05:18

投稿

teamikl
teamikl

スコア8760

test CHANGED
@@ -1,4 +1,4 @@
1
- 問題点: スレッドが正しく使えてません
1
+ 問題点: スレッドが~~正しく使えてません~~ 用途に合った使い方になってません
2
2
 
3
3
 
4
4
 

2

追記: マルチ「プロセス」時のロギングの設定に言及

2021/06/27 05:18

投稿

teamikl
teamikl

スコア8760

test CHANGED
@@ -120,11 +120,21 @@
120
120
 
121
121
 
122
122
 
123
- # logger モジュールは、スレッドセーフなので、どこからでも安全に呼び出せます。
123
+ # logging モジュールは、スレッドセーフなので、どこからでも安全に呼び出せます。
124
124
 
125
125
  # print の代わりに利用 logger.info, logger.debug, logger.error, 等
126
126
 
127
127
  logger.debug(f"debug message: {fn=}") # f-string で変数 fn を表示
128
+
129
+
130
+
131
+
132
+
133
+ # ※ multiprocessing 利用があったので追記
134
+
135
+ # マルチ「プロセス」の場合は、この設定では不十分で、
136
+
137
+ # 追加でプロセス間のキューを用いた設定・構成が必要になります。
128
138
 
129
139
  ```
130
140
 

1

追記: スレッドの使い方について

2021/06/26 11:18

投稿

teamikl
teamikl

スコア8760

test CHANGED
@@ -83,3 +83,103 @@
83
83
  同時利用自体は可能なのですが、注意が必要な点は、
84
84
 
85
85
  双方のイベントループを止めないように配慮しないと、片方が応答なしになってしまいます。
86
+
87
+
88
+
89
+ ---
90
+
91
+ 追記: コードの全貌をまだ把握しきれてないので、読みながら判明した点を追記します。
92
+
93
+
94
+
95
+ 問題点: スレッドの使い方が、ボタンを押したときにスレッド生成、
96
+
97
+ スレッド内ではキューへの出し入れしか仕事をしていない。
98
+
99
+
100
+
101
+ 確認方法: logging モジュールを使い、関数がどのスレッドで実行されているかを表示する。
102
+
103
+
104
+
105
+ ```python
106
+
107
+ # ファイルの先頭で
108
+
109
+ import logging
110
+
111
+ logger = logging.getLogger(__name__)
112
+
113
+
114
+
115
+ # ログにスレッド名を表示&ロギングを有効にする設定
116
+
117
+ # if __name__ == "__main__": 内に置きたいが、なければファイル先頭でもok
118
+
119
+ logging.basicConfig(level=logging.DEBUG, format="[%(threadName)-10s][%(levelname)-8s] %(message)s")
120
+
121
+
122
+
123
+ # logger モジュールは、スレッドセーフなので、どこからでも安全に呼び出せます。
124
+
125
+ # print の代わりに利用 logger.info, logger.debug, logger.error, 等
126
+
127
+ logger.debug(f"debug message: {fn=}") # f-string で変数 fn を表示
128
+
129
+ ```
130
+
131
+
132
+
133
+ ----
134
+
135
+ スレッドは、解りやすくリソース毎に割り当てるなら
136
+
137
+ - 音楽再生スレッド(portaudio)
138
+
139
+ - 波形プロットのスレッド(pygame?)
140
+
141
+ - メインスレッド(PySimpleGUI)
142
+
143
+ とします。
144
+
145
+ 必要なキューは、GUI -> 音楽再生停止の制御と、wavデータ読み出し→波形プロット
146
+
147
+
148
+
149
+ メイン: pygame+PySimpleGUI <=> サブスレッド: portaudio にする方法もありますが、
150
+
151
+ 分離した方が、バックエンドを別のライブラリに差し替え等といった時に都合の良い設計になります。
152
+
153
+
154
+
155
+ スレッドの解りやすい使い方は、
156
+
157
+ ボタンを押したときに毎回生成ではなく、スレッドは予め稼働させておいて
158
+
159
+ ボタンを押したときに動き出すように、queue や threading.Eevnt 等で制御します。
160
+
161
+ メインスレッド終了時に、スレッドは正しく終了させるように構成する。
162
+
163
+ (スレッド内でのループやブロック処理は抜けるように。→リソース解放処理を確実に呼び出す)
164
+
165
+
166
+
167
+ ----
168
+
169
+ pygame をメインスレッド以外で使えるかは、試してないので解りませんが、
170
+
171
+ 使えない場合は メインスレッドの利用をPySimpleGUI と入れ替え。
172
+
173
+
174
+
175
+ GUIライブラリではメインスレッドでしか使えない制限がある事があります。
176
+
177
+ (正確には、初期化したスレッドと同じスレッド内でないと誤動作の原因に)
178
+
179
+
180
+
181
+ 基本は、ウィンドウを閉じた時に終了したい場合が多いので、
182
+
183
+ GUI をメインスレッドにした方が都合が問いのですが
184
+
185
+ PySimpleGUI 内で使われている tkinter は別スレッドでも大丈夫です。