python_メインのクラスが別のスレッドでのタスクの完了の回数を知りたいとき

 

pythonにおいて


複数回数、同じタスクを処理するスレッドを


メインの関数で作成しスタートしてから、

ランダムなタイミングで停止させるときに、


そのスレッド内に記述したタスクを

何回完了したのか知りたいときには、



まず、メインのクラス内に

タスク用のスレッドを保持し、(thread A)

そのタスク用のスレッドを停止させるスレッドを保持し、(thread B)


この2つのスレッドA,Bの間では 停止させるタイミングを知るための

threading.Eventのインスタンスを共有させると思うのですが、


メインのクラスがスレッドAのタスクの完了回数を知るためには


別のリソース用のクラスのインスタンスを

メインのクラスと、スレッドAの間で共有させるものなのでしょうか?




そのアプローチは適切で、以下のように整理できます。


1. **メインのクラス** 


   - タスク用スレッド(スレッドA)と停止制御スレッド(スレッドB)を管理する。

   

   - `threading.Event`を使用してスレッド間の停止タイミングを制御する。

   

   - タスクの完了回数を追跡するためにリソース用のクラスをスレッドAと共有する。

   


2. **スレッドA**  

   - タスクを繰り返し実行し、完了するごとに共有リソースに完了回数を記録する。

   

   - `threading.Event`の状態を監視し、停止条件を確認する。


3. **リソース用のクラス**

  

   - スレッド間で共有され、スレッドAがタスクの完了回数を記録し、

メインスレッドがその値を読み取る。


### 実装例


以下のコードで説明します:


```python

import threading

import time

import random


# タスクの完了回数を管理するリソースクラス

class TaskCounter:

    def __init__(self):

        self.count = 0

        self.lock = threading.Lock()


    def increment(self):

# スレッドセーフにするためロックを使用

        with self.lock:  

            self.count += 1


    def get_count(self):

        with self.lock:

            return self.count



# タスク用のスレッドA

def task_thread(stop_event, task_counter):

# stop_event がセットされるまでループ

    while not stop_event.is_set():

        # タスクを実行 (ここではダミーの処理)

        time.sleep(random.uniform(0.1, 0.5))  # タスクの実行時間

        task_counter.increment()  # 完了回数を増やす

        print("Task completed")



# 停止制御用のスレッドB

def control_thread(stop_event, duration):

    time.sleep(duration)  # 指定時間後に停止

    stop_event.set()

    print("Stop event set")


# メインスレッド

def main():

    stop_event = threading.Event()  # 停止フラグ

    task_counter = TaskCounter()  # タスク完了回数を管理するインスタンス


    # スレッドAを作成してスタート

    thread_a

= threading.Thread(

target=task_thread, 

args=(stop_event, task_counter))

    thread_a.start()


    # スレッドBを作成してスタート

    duration = 5  # スレッドAを5秒後に停止

    thread_b

= threading.Thread(target=control_thread, 

args=(stop_event, duration))


    thread_b.start()


    # スレッドA, Bの終了を待機

    thread_a.join()

    thread_b.join()


    # タスク完了回数を表示

    print(f"Total tasks completed:

{task_counter.get_count()}")


if __name__ == "__main__":

    main()

```


### 説明


1. **共有リソースクラス (TaskCounter)** 

 

   - `increment`メソッドでタスクの完了回数を増加。

   

   - `get_count`メソッドで完了回数を取得。

   

   - ロックを使ってスレッドセーフに管理。



2. **スレッド間通信 (threading.Event)** 

 

   - `stop_event`を使用してスレッドAのループを終了。

   

   - スレッドBが指定時間後に`stop_event.set()`を呼び、

スレッドAに停止を通知。


3. **タスク完了回数の追跡**  


   - タスク完了ごとに`task_counter.increment()`を呼び出して

完了回数を記録。

   

   

   - メインスレッドが`task_counter.get_count()`を呼び出して

結果を表示。


これでスレッド間の同期が安全かつ簡潔に実現できます。


コメント