2017-10-16 9 views
0

私はrpiでLEDストリップを使って一度に1文字ずつメッセージを表示する簡単なプロジェクトを持っています。新しいメッセージを表示するときにLEDが消えるまで、LEDがランダムに点灯して固まってしまうことがあります。シンプルなpythonマルチスレッド共有変数

私の解決策は、約2秒ごとにストリップをクリアする別のスレッドを作成することです。そのため、LEDがランダムにオンになると、すぐに再びオフになります。

明らかに、メッセージが表示されている間にそのスレッドが表示をクリアしないようにするため、メッセージが現在表示されているかどうかを追跡するグローバル変数を作成しました。

displaying = False 


def display(msg): 
    global displaying 
    displaying = True 
    for c in msg: 
     turn_all_leds_off() 
     display_char(c) 
     time.sleep(1) 
     turn_all_leds_off() 
     time.sleep(.2) 
    time.sleep(1) 
    displaying = False 


def listen_on_client(): 
    while True: 
     global displaying 
     if not displaying: 
      get_new_messages_from_server_and_display_them() 
     time.sleep(2) 


def clear_errors(): 
    while True: 
     global displaying 
     if not displaying: 
      display(" ") 
     time.sleep(2) 


t1 = Thread(target=listen_on_client, args=()) 
t2 = Thread(target=clear_errors, args=()) 
t1.start() 
t2.start() 

問題があり、変動表示が動作していないよう:

は、ここでは、関連するコードのストリップダウンバージョンです。エラークリアスレッドがチェックを行うと、表示が常に偽であるかのように動作します。私は競合状態を心配する必要があるときに他のプログラミング言語でロックを使用する必要がありましたが、正直言って、ナノ秒ではなく数秒で動作するようにするだけです。これは競合状態ではなく、変数が各スレッドにキャッシュされ、Pythonにvolatileキーワードがないようです。これは他のSOの質問がそれを行うように提案したのと似ていますので、何が間違っているのかよく分かりません。何か案は?

答えて

0

私は、うまくいけばキャッシングを避けるために、whileループの中で宣言されたグローバルを持っていましたが、それは実際に反対の効果を持っているようでした。

def clear_errors(): 
    while True: 
     global displaying 

から

def clear_errors(): 
    global displaying 
    while True: 

にすべてを変える

はそれを修正しました。しかし、なぜか分からない。

関連する問題