Pythonのthreading.Timerで定期的に処理を呼び出すサンプル


Pythonはほとんど使いませんが、友人のコードを見ていて変な箇所を見つけて調べて問題にあたりました。

<http://bty.sakura.ne.jp/wp/archives/71>

の例で

[code]

    import threading
    
    def hello():
        print "helohelo"
    
    t=threading.Timer(5,hello)
    t.start()
    
[/code]

というものがあります。5秒後に別スレッドでhello()を実行します。これは納得です。つづいて一定時間ごとに処理を繰り返すサンプルとして

[code]

    import threading
    
    def hello():
        print "helohelo"
        t=threading.Timer(1,hello)
        t.start()
    
    
    t=threading.Thread(target=hello)
    t.start()
    
[/code]

これに違和感を覚えます。hello()の中でまた5秒後に別スレッドを作りhello()を実行するコードが入っています。これを実行したら次々スレッドが生成されて、やがてリソースを食いつぶしてプログラムが落ちるのではないかと思うのですが、いかがでしょうか？

あれこれ調べていて

<http://www.webscalability.com/blog/2016/02/simple-example-of-using-the-
threading-timer-class-in-python/>

でも同じようにincの中でincを呼び出しています。

自分で簡単なコードを書いてみました。

[code]

    import threading
    import time
    
    def hello():
        print("現在のスレッドの数: " + str(threading.activeCount()))
        print("[%s] helohelo!!" % threading.currentThread().getName())
        t=threading.Timer(1,hello)
        t.start()
    
    if __name__=='__main__':
        t=threading.Thread(target=hello)
        t.start()
    
[/code]

実行結果は

[code]

    現在のスレッドの数: 2
    [Thread-1] helohelo!!
    現在のスレッドの数: 2
    [Thread-2] helohelo!!
    現在のスレッドの数: 2
    [Thread-3] helohelo!!
    現在のスレッドの数: 2
    [Thread-4] helohelo!!
    現在のスレッドの数: 2
    [Thread-5] helohelo!!
    現在のスレッドの数: 2
    [Thread-6] helohelo!!
    現在のスレッドの数: 2
    [Thread-7] helohelo!!
    
[/code]

でした。Threadの名前は毎回異なっていて別スレッドが作られているようですが、スレッドの数自体は2から増えていないののでこれで問題ないのでしょうか？

追記：再帰呼び出しの形になっていますが、別スレッドで動いているためthreading.Timer(1,hello)の直後に親スレッドは消えてしまうことによってこのコードは安定して動いていると言うことでしょうか？こういう書き方はスレッド生成元が子スレッドの終了を見て再起動させるとか、スレッドの中で無限ループ＋sleepさせるよりスマートなのかも知れません。

質問がぼやけてしまったので再確認しますが、Pythonを使い慣れている方にとってこの末尾で自分自身を別スレッドで走らせるというのは自然なのでしょうか？




スレッド数の挙動に関しては`hello`関数内で`t.start()`がよばれた後そのスレッドは破棄されます．
言及されているように`t.start()`の後に無限ループするコードを追加するとスレッド数が増え続けるのがわかります．
またスレッド数が2のままなのはPython本体のmainスレッドとそのとき動作しているhello関数のスレッドが同時に動作してるからです．

