【Python】スレッド間で変数を共有する方法

やりたいこと

スレッド間で変数を共有したい。例えば関数Aで変数xに1を入れたら、関数Bの変数xに1が入るみたいな。

なんでそんなことしたいのか?

あれです。何か時系列シミュレーションしようとしたときはスレッドで流さんとイケナイ。んで機能A(スレッドA)の出力が機能B(スレッドB)の入力となるようなやつはどういう風に渡してあげればいいんかいな?

やったこと

結論を言ってしまえばqueueを使う。機能Aの出力をQueueに入れて、機能BにQueueを引き渡してQueueの中身を拾う。

実際のコード

import time
import sys
import threading
import queue
from datetime import datetime, timedelta

#入力信号を作る関数
def test_input(event, q_event):
    time.sleep(0.1)
    event = 1
    q_event.put(event)
    time.sleep(1)
    event = 0
    q_event.put(event)

#入力信号を受ける関数StopRequestがTrueになったら終わる。
def recv(event, q_event, StopRequest, q_StopRequest):
    StopRequest = q_StopRequest.get()
    i = 0
    while StopRequest == False:
        if not q_event.empty():
            event = q_event.get()
        i = i + 1

        if not q_StopRequest.empty():
            StopRequest = q_StopRequest.get()
        print(StopRequest, i, event)
        time.sleep(0.1)

#シミュレーションの時間を数える関数
def test1(StopRequest, q_StopRequest):
    print("##############simulation START##############")

    StopRequest = False
    q_StopRequest.put(StopRequest)

    starttime = datetime.now()
    endtime = starttime + timedelta( seconds = 5)
    i = 1
    while endtime > datetime.now():
        now = datetime.now()
        i = i + 1
        time.sleep(1)

    StopRequest = True
    q_StopRequest.put(StopRequest)
    time.sleep(0.1)
    print("##############simulation END##############")
    sys.exit()

def main():

    q_event = queue.Queue()
    event = 0
    q_StopRequest = queue.Queue()
    StopRequest = False

    #スレッドを開始
    thread_test1 = threading.Thread(target=test1, args=(StopRequest, q_StopRequest))
    thread_testin = threading.Thread(target=test_input, args=(event, q_event))
    thread_recv = threading.Thread(target=recv, args=(event, q_event, StopRequest, q_StopRequest))
    thread_recv.start()
    thread_test1.start()
    thread_testin.start()

    
if __name__ == "__main__":
    main()

test_input関数でeventという変数を作っている。これをrecv関数に渡す。一緒にq_eventを渡してrecvが拾う。これで渡している。

StopRequestも同じように渡している。これをしないとrecv内のwhile文が終わらん。

q.empty()はQueueの中が空かどうかを判定する関数。

実行結果


0でスタートして0.1秒後に1入れて、1秒後に0にする。

まぁいいんじゃないかな。

おわりんご。


この記事が気に入ったらサポートをしてみませんか?