home ホーム search 検索 -  login ログイン  | reload edit datainfo version cmd icon diff delete  | help ヘルプ

Python/codepiece/threading, event, console, Ctrl-C (v1)

Python/codepiece/threading, event, console, Ctrl-C (v1)

Python / codepiece / threading, event, console, Ctrl-C (v1)
id: 932 所有者: msakamoto-sf    作成日: 2011-03-11 11:11:47
カテゴリ: Python 

かなりニッチなモデルについて実験。

  1. スレッド1:対話形式処理モードと監視処理モードの二つのモードの間を遷移する。
  2. スレッド2:コンソールでCtrl-Cによる割り込みを受け付け、スレッド1を対話形式処理モードに切り替える。

スレッド1の監視処理はbusyループではなく、TimeOut付きの短期間のwait()を無限ループ中で呼び出すイメージ。
スレッド1の初期状態は監視処理モード。スレッド2による切り替えで対話形式処理モードに遷移する。
対話形式処理モードにおいて監視処理への切り替えコマンドを受け取ると、再び監視処理モードに遷移する。

スレッド間の連携については threading.Event を使ってみる。

予備実験として threading.Event を使ったスレッド間連携を試してみる。
thread_and_event1.py:

import threading
import time
 
def mythread(myevent):
  count = 1
  while True:
    myevent.wait(1)
    print "wakeup(%d)" % (count)
    count += 1
    if myevent.isSet():
      print "break"
      break
 
event = threading.Event()
t = threading.Thread(target=mythread, args=(event,))
t.start()
 
# 5秒後にevent発生
time.sleep(5)
print "(main):event set"
event.set()
 
t.join()

実行例(Python2.5)

> python thread_and_event1.py
wakeup(1)
wakeup(2)
wakeup(3)
wakeup(4)
(main):event set
wakeup(5)
break
>

予備実験で threading.Event によるスレッド間連携を確認できた。

本題となるモード切り替えやCtrl-Cによるスレッド連携の実装サンプル:
thread_and_event2.py:

import threading
import time
import signal
 
def mythread(myevent):
  busy_work = threading.Event() # 小刻みな監視処理用のダミーEvent
  continue_flag = True
  count = 1
  while continue_flag:
    # 小刻みな監視処理
    if busy_work.wait(1):
      print "Never happen"
    else:
      print "mythread(%d)" % (count)
      count += 1
      # 連携イベントをチェック
      myevent.wait(1)
      if myevent.isSet():
        print "Interrupted"
        # 対話形式スタート
        while True:
          command = raw_input(">>")
          if command == "q":
            continue_flag = False
            break # 監視処理に戻る+フラグにより終了へ
          elif command == "g":
            break # 監視処理に戻る
          else:
            print "You type: " + command
        myevent.clear()
  print "end"
 
event = threading.Event()
t = threading.Thread(target=mythread, args=(event,))
t.start()
 
while True:
  try:
    # 1秒間ずつスレッドの終了チェック
    t.join(1)
    if not t.isAlive():
      break
  except KeyboardInterrupt:
    # Ctrl-C による割り込み発生
    print "interruption set"
    event.set()

実行例(Python2.5)

> python thread_and_event2.py
mythread(1)
mythread(2)
mythread(3)
(Ctrl-C)
interruption set
Interrupted
>>foo
You type: foo
>>bar
You type: bar
>>g
mythread(4)
mythread(5)
(Ctrl-C)
interruption set
mythread(6)
Interrupted
>>abc
You type: abc
>>q
end
>

Ctrl-Cによる監視→対話へ切り替え、対話形式でのコマンド入力による監視モードへの復帰やスレッドの終了を実現できた。

なお raw_input() 中に Ctrl-C を受信するとEOFErrorが発生する点に注意が必要。
EOF発生時には空文字列入力として続行する例:

       # 対話形式スタート
       while True:
         command = raw_input(">>")


       # 対話形式スタート
       while True:
         command = ""
         try:
           command = raw_input(">")
         except EOFError:
           pass


プレーンテキスト形式でダウンロード
現在のバージョン : 1
更新者: msakamoto-sf
更新日: 2011-03-11 13:40:50
md5:f468c3211bae713216406cc12013c3ec
sha1:1429a43e7d4a4ff88e449ea4185fde4ffa2eee02
コメント
コメントを投稿するにはログインして下さい。