グローバルに表示され、変更可能な変数ではなく、pushed
内部で定義されたローカル変数のみが表示されるため、機能しません。method
pushed
代わりに必要なのは次のとおりです(ただし、正しい解決策については下にスクロールしてください):
pushed = False
@post('/button')
def action():
global pushed # needed because otherwise assigning to `pushed` will
# just create a local variable shadowing the global one
pushed = True
redirect("/button")
def method():
# pushed = False <----- this line is not needed, and if enabled, will, again,
# create a local variable shadowing the global one
global pushed # again, otherwise the `pushed = False` statement will create a local variable
while True: # use real booleans, i.e. True/False not 1/0
if pushed:
print "push recieved"
pushed = False
method()
注:スニペット内に追加したコメントに注意してください。
しかし、グローバル変数 (または通常の変数) を介してスレッドと通信することは、他の複数のスレッドが同じ変数に同時にアクセス (読み取りまたは書き込み) する可能性があるため、悪い習慣です。代わりに、スレッド間でイベントを通知するには、キューを使用します。
from Queue import Queue, Empty
button_pressed = Queue()
@post('/button')
def action():
button_pressed.put(1) # can be any value really
redirect("/button")
def method():
while True:
try:
button_pressed.get_nowait()
except Empty:
# NOTE: if you don't do anything here, this thread
# will consume a single CPU core
pass
else:
print "push recieved"
get_nowait()
何かがput
キューに入っているかどうかを確認し、そうであればそれを返します。それ以外の場合は、すぐに が発生しEmpty
ます。ゼロ以外のタイムアウトを渡すことも、タイムアウトなしで呼び出すこともできます。この場合、キューで何かが利用可能になるまで待機します。
.get()
スレッドが無駄に CPU を消費しないようにするには、nowait バージョンよりもタイムアウトを使用する方がよいでしょう。
さらに、スレッドを開始する行や呼び出す行などのコードはmethod()
、モジュールの最上位スコープに直接配置しないでください。代わりに、次のように条件付きで呼び出します。
if __name__ == '__main__':
threading.Thread(target=run, kwargs=dict(host='localhost', port=8080)).start()
method()
このようにして、.py
ファイルがモジュールとしてインポートされた場合ではなく、ファイルが直接実行された場合にのみコードが実行されます。また、通常どおり呼び出しrun()
、代わりにmethod
スレッド内に配置することを検討してください。