8.8. "sched" --- イベントスケジューラ
*************************************

**ソースコード:** Lib/sched.py

======================================================================

"sched" モジュールは一般的な目的のためのイベントスケジューラを実装する
クラスを定義します:

class sched.scheduler(timefunc, delayfunc)

   "scheduler" クラスはイベントをスケジュールするための一般的なインタ
   フェースを定義します。それは "外の世界" を実際に扱うための2つの関数
   を必要とします --- *timefunc* は引数なしで呼ばれて 1 つの数値を返す
   callable オブジェクトでなければなりません (戻り値は任意の単位で「時
   間」を表します)。 *delayfunc* は 1 つの引数を持つ callable オブジェ
   クトでなければならず、その時間だけ遅延する必要があります (引数は
   *timefunc* の出力と互換)。 *delayfunc* は、各々のイベントが実行され
   た後に引数 "0" で呼ばれることがあります。これは、マルチスレッドアプ
   リケーションの中で他のスレッドが実行する機会を与えるためです。

例:

   >>> import sched, time
   >>> s = sched.scheduler(time.time, time.sleep)
   >>> def print_time(): print "From print_time", time.time()
   ...
   >>> def print_some_times():
   ...     print time.time()
   ...     s.enter(5, 1, print_time, ())
   ...     s.enter(10, 1, print_time, ())
   ...     s.run()
   ...     print time.time()
   ...
   >>> print_some_times()
   930343690.257
   From print_time 930343695.274
   From print_time 930343700.273
   930343700.276

マルチスレッド環境において、 "scheduler" クラスにはスレッドセーフのた
めの制限があります。イベントキューが空になるまでは、実行中のスケジュー
ラで現在中断中でメインスレッドを足止めしているタスクの前に、新しいタス
クを挿入することはできません。代わりに、より推奨される方法として、
"threading.Timer" クラスを利用してください。

例:

   >>> import time
   >>> from threading import Timer
   >>> def print_time():
   ...     print "From print_time", time.time()
   ...
   >>> def print_some_times():
   ...     print time.time()
   ...     Timer(5, print_time, ()).start()
   ...     Timer(10, print_time, ()).start()
   ...     time.sleep(11)  # sleep while time-delay events execute
   ...     print time.time()
   ...
   >>> print_some_times()
   930343690.257
   From print_time 930343695.274
   From print_time 930343700.273
   930343701.301


8.8.1. スケジューラオブジェクト
===============================

"scheduler" インスタンスは以下のメソッドと属性を持っています:

scheduler.enterabs(time, priority, action, argument)

   Schedule a new event. The *time* argument should be a numeric type
   compatible with the return value of the *timefunc* function passed
   to the constructor. Events scheduled for the same *time* will be
   executed in the order of their *priority*. A lower number
   represents a higher priority.

   イベントを実行することは、 "action(*argument)" を実行することを意味
   します。 *argument* は *action* のためのパラメータを保持するシーケ
   ンスでなければいけません。

   戻り値は、イベントのキャンセル後に使われるかもしれないイベントです
   ("cancel()" を見よ)。

scheduler.enter(delay, priority, action, argument)

   時間単位以上の *delay* でイベントをスケジュールします。相対的時間以
   外の、引数、効果、戻り値は、 "enterabs()" に対するものと同じです。

scheduler.cancel(event)

   キューからイベントを消去します。もし *event* がキューにある現在のイ
   ベントでないならば、このメソッドは "ValueError" を送出します。

scheduler.empty()

   もしイベントキューが空ならば、Trueを返します。

scheduler.run()

   すべてのスケジュールされたイベントを実行します。この関数は次のイベ
   ントを (コンストラクタへ渡された関数 "delayfunc()" を使うことで) 待
   ち、そしてそれを実行し、スケジュールされたイベントがなくなるまで同
   じことを繰り返します。

   *action* あるいは *delayfunc* は例外を投げることができます。いずれ
   の場合も、スケジューラは一貫した状態を維持し、例外を伝播するでしょ
   う。例外が *action* によって投げられる場合、イベントは "run()" への
   呼出しを未来に行なわないでしょう。

   イベントのシーケンスが、次イベントの前に、利用可能時間より実行時間
   が長いと、スケジューラは単に遅れることになるでしょう。イベントが落
   ちることはありません; 呼出しコードはもはや適切でないキャンセルイベ
   ントに対して責任があります。

scheduler.queue

   読み取り専用の属性で、これから起こるイベントが実行される順序で格納
   されたリストを返します。各イベントは、次の属性 time, priority,
   action, argument を持った *named tuple* の形式になります。

   バージョン 2.6 で追加.
