果報は寝て待て: 11月 2021

2021年11月29日月曜日

pythonでのスレッド間通信

 またまたpythonねたです。次のような仕様のプログラムを作成中、スレッド間のデータの受け渡しが必要になりましたので、使い方の覚えとして記録しておきます。

1 webカメラで30フレーム/秒の画像を取り込み画面に表示する。

2 sirial通信でaruduinoのI/Oの値(オン、オフ)を取り込む(1回/秒)

3 それをトリガーに録画を開始、停止する。

4 累積された録画データが30分たまればハードディスクに落としていく。

 

画像処理は 1秒に30回まわります。aruduinoからの処理は1秒に1回回ります。ということでスレッド間通信が必要となりました。しかしオンオフだけでいいので今回はイベントを使います。

スレッド間のデータの受け渡しのサンプル、基本の使い方です。 

 

import threading
import time

def proc1():
    event.set()
    time.sleep(4)
    event.set()

def proc2():
    time.sleep(2)
    event.clear()
    time.sleep(5)

if __name__ == "__main__":
    event = threading.Event()
    th1 = threading.Thread(target=proc1)
    th2 = threading.Thread(target=proc2)
    th1.start()
    th2.start()

 これに1行ごとのevent内容をプリントさせたのが以下のプログラムです。

 

import threading

import time

def proc1():
    print("process1: start")
    print("proc1 event is ",event.is_set())
    event.set()
    print("proc1 event is set as ",event.is_set())

    
    time.sleep(4)
    print("proc1 event is ",event.is_set())
    event.set()
    print("proc1 event is set as ",event.is_set())

    print("process1: end")

def proc2():

    print("process2: start")

    time.sleep(2)
    print("proc2 event is ",event.is_set())
    event.clear()
    print("proc2 event is set as ",event.is_set())
 
    time.sleep(5)
    print("process2: end")

if __name__ == "__main__":
    event = threading.Event()
    th1 = threading.Thread(target=proc1)
    th2 = threading.Thread(target=proc2)
    th1.start()
    th2.start()


実行の結果

process1: start
process2: start
proc1 event is  False              # 最初は False です。        

proc1 event is set as  True      # proc1で True に変更されました
proc2 event is  True               # proc2で呼び出した時に True でした。
proc2 event is set as  False     # proc2で False に変更されました
proc1 event is  False              # proc1で再度呼び出した時に False でした。
proc1 event is set as  True     # proc1で True に変更されました
process1: end
process2: end

 

proc1とproc2の間でeventの値をきちんと引き継いでいます。このeventを録画スタート、ストップに使ってプログラムを作ります。