マニュアルページ queue.3




名前

     queue - タスクライブラリのリストの管理


形式

     #include <task.h>
     enum qmodetype { EMODE, WMODE, ZMODE };
     class qhead: public object {
     public:
          // 公開されたコンストラクタ
          qhead(qmodetype mode=WMODE, int size=10000);
          // 公開された仮想関数
          virtual objtype     o_type();
          virtual int    pending();
          virtual void   print(int, int=0);
          // 公開されたその他の関数
          qhead*    cut();
          object*   get();
          int  putback(object*);
          int  rdcount();
          int  rdmax();
          qmodetype rdmode();
          void setmode(qmodetype);
          void      setmax(int);
          void splice(qtail*);
          qtail*    tail();
     };
     class qtail: public object {
     public:
          // 公開されたコンストラクタ
          qtail(qmodetype mode=WMODE, int size=10000);
          // 公開された仮想関数
          virtual objtype     o_type();
          virtual int    pending();
          virtual void   print(int, int = 0);
          // 公開されたその他の関数
          qtail*    cut();
          qhead*    head();
          int  put(object*);
          int  rdmax();
          qmodetype rdmode();
          int  rdspace();
          void setmode(qmodetype);
          void setmax(int);
          void splice(qhead*);
     };


機能説明

     タスクシステムには、一般的なキューメカニズムが用意されていま
     す。このキューは、クラス object から派生したオブジェクトの先
     入れ先出しリストです。クラス object に関しては、  task(3C++)
     を参照してください。このキュー自体に直接アクセスすることはで
     きませんが、2 つのクラス qhead および qtail のメンバー関数を
     用 い て ア ク セスすることができます。クラス qhead により、
     キューの先頭にアクセスできます。これは主に、リストの先頭の項
     目 を削除するときに使用します。 qtail クラスにより、キューの
     終端にアクセスできます。これは主に、リストの終端に項目を追加
     するときに使用します。

     キューを作成するためには、まず qhead オブジェクトを作成 し、
     メンバー関数 qhead::tail() を呼び出して対応する qtail にアク
     セスします。例を示します。
          qhead qh;      // キューを作成
          qtail *qtp = qh.tail();  // qtail を取り出す
     また、クラス qtail のオブジェクトを作成した後で、メンバー 関
     数 qtail::head() を用いて対応する qhead にアクセスする方法も
     あります。次に示すのは、ヒープ・オブジェクトだけを使用した例
     です。
          qtail *qtp = new qtail;  // キューを作成
          qhead *qhp = qtp->head();     // qhead を取り出す

     この 2 つのクラスのコンストラクタは、引数にキューのモード と
     キュー の 最 大 サ イズの 2 つ (ともに省略可能) を持ちます。
     キューモードは、キューの通常の操作には影響を与えず、保留状態
     の キュー に対する操作を試みた場合に何が発生するかを指定しま
     す。キューモードについては後述します。キューの サ イ ズ は、
     キューを構成する項目の最大数です。これは、最大のサイズを持つ
     現実のキューをモデル化するのに利用できます。デフォルトのサイ
     ズは 10,000 項目です。サイズは、メンバー関数 setmax() によっ
     ていつでも再設定できます。キューの各項目に領域があらかじめ割
     り当てられることはありません。

     キューが作成できれば、メンバー関数 qtail::put() によってそこ
     にオブジェクトを追加したり、メンバー関数 qhead::get() によっ
     てキューの先頭のオブジェクトを取り出すことができます。

     クラス object から派生されるすべてのクラスと同様に、各キュー
     はそれが使用可能であるか保留中であるかの定義を持ち、その定義
     はキューの先頭と終端とで異なります。 qtail は、それがフル 状
     態になっている場合、すなわち、最大数のオブジェクトがすでに含
     まれている場合は保留状態になります。 qhead は、それが空の 場
     合に保留状態になります。

     qhead と qtail はそれぞれのモードを持っていて、コンストラ ク
     タ の モード引数によって設定されます。モードは、メンバー関数
     setmode() によっていつでも変更できます。同じキューの先頭と終
     端でモードが同じである必要はありません。モードは、次のいずれ
     かでなければなりません。

     WMODE
          :  フル状態の qtail に追加したり、空の  qhead
          か ら 削 除を行うように要求があると、その要求を中断しま
          す。他のモードが指定されない場合は、このモードに設定 さ
          れます。

     ZMODE
          ゼロモード : フル状態の qtail に追加したり、空の  qhead
          から削除を行うように要求があると、ゼロを返します。

     EMODE
          エラーモード : フル状態の qtail に追加 し た り、 空 の
          qhead  か ら削除を行うように要求があると、 task_error()
          を呼び出します。

     キューは、カットしたり分割することができます。それに よ り、
     フィルタや他のタスクをキューの処理に挿入することが可能です。
     詳細については、メンバー関数 cut() および splice() のとこ ろ
     で説明します。

  クラス qhead
     qhead qh(m, s);
          qhead 型のオブジェクトとそれに対応するキューを作成し ま
          す。 キュー の モードは m 、最大サイズは s に設定されま
          す。モードとサイズのパラメタの結果は、上に示したとお り
          です。メンバー関数 tail() は、キューに対応する qtail オ
          ブジェクトを指すポインタを返します。

     objtype ot = qh.o_type();
          この仮想関数は、オブジェクトの種類を返します。 qhead の
          場合、オブジェクトの種類は QHEAD となります。

     int ispending = qh.pending();
          この仮想関数は、対応するキューが空の場合はゼロ以外の 値
          (真) を、それ以外の場合はゼロ (偽) を返します。

     qh.print(how);
          対応するキューに関するデータを stdout ( cout ではない )
          に 出力します。 int 型の第 1 引数 how で VERBOSE ビット
          がセットされていれば、キュー内のすべてのオブジェクト に
          関する情報を出力します。第 2 引数は内部的に使用するもの
          で、デフォルトはゼロです。

     qhead *qhp = qh.cut();
          新しい qhead を作成して元のキューにつなぎ、そのキューを
          指 すポインタを返します。オリジナルの qhead ( qh ) を新
          しい空のキューを指すように変更します。この新しい キュー
          に 対応する qtail を取り出す場合は、 qh.tail() を使用し
          てください。結果として、 qhp はオリジナルの qhead を 指
          すようになり、オリジナルの qtail はオリジナルのキューに
          対応したままです。つまり、次のような状況になります。
          qhp->get()
               オリジナルのキューの先頭の項目を取り出す。
          qhp->tail()->put(op)
               オリジナルのキューにオブジェクトを追加する。
          qh.get()
               新しいキューに項目が登録 (追加) されていれば、その
               先頭の項目を返す。

          qh.tail()->put(op)
               新しいキューにオブジェクトを追加する。

          この方法により、そのキューのオリジナルの qhead や qtail
          を 使用して、コードを変更することなく既存のキューにフィ
          ルタを挿入することができます。このフィルタは、 qtail を
          用 いてキューに追加されたオブジェクトを取り出すときには
          qhp->get() を使用します。また、新しいキューにオブジェク
          ト を登録 (追加) する場合は、 qhp->tail()->put(op) の等
          価を使用します。このようにして追加されたオブ ジェ ク ト
          は、オリジナルの qhead を参照するコードによって取り出さ
          れます。オリジナルのキューに対して追加や取り出しを行 う
          既 存のコードは、フィルタを通してオブジェクトを操作する
          ようになります。キューは、 qhead::splice() によって復元
          することができます。 qtail には cut と splice の 2 つの
          関数が対応づけられていますが、この 2 つの関数のペアは同
          じ オブジェクト ( qhead または qtail のどちらか) から使
          用しなければなりません。

     object *op = qh.get();
          qh に対応するキューが空でなければ、キューの先頭の オ ブ
          ジェ クトを削除し、それを指すポインタを返します。キュー
          が空の場合、その動作は、 qh のモードに依存します。 モー
          ド が WMODE の場合、 get() 呼び出しのタスクはオブジェク
          トがキューに置かれるまで中断されます。モードが ZMODE の
          と き、NULL ポインタを直ちに返します。モードが EMODE の
          とき、ランタイム・エラーが発生し、 object::task_error()
          が呼び出されます。

     int ok = qh.putback(op);
          qt に対応するキューがフル状態でなければ、 op が指すオブ
          ジェ ク ト をキューの先頭に置き、値 1 (真) を返します。
          qhead と、関数 putback() および get() を使用す る こ と
          で、 キューをスタックのように使用できます。キューがフル
          状態のとき、動作は qh のモードに依存します。 モー ド が
          WMODE の場合、 putback() を呼び出すタスクは、キューがフ
          ルではない状態になるまで中断されます。モードが ZMODE の
          場合、直ちにゼロを返します。モードが EMODE の場合、ラン
          タイム・エラーが発生し、 object::task_error() が呼び 出
          されます。

     int i = qh.rdcount();
          対応するキューに現在含まれているオブジェクトの数を返 し
          ます。

     int i = qh.rdmax();
          対応するキューに入れることができるオブジェクトの (現 在
          の) 最大数を返します。

     qmodetype qm = qh.rdmode();
          qh の現在のモード (WMODE、EMODE、ZMODE のいずれか) を返
          します。

     qh.setmode(qm);
          qh のモードを qm に設定します。 qm は、 WMODE、 EMODE、
          ZMODE のいずれかです。

     qh.setmax(max);
          対応するキューに入れることができる項目の最大数を max に
          設 定します。最大数は、キュー内の現在のオブジェクトの数
          より小さい値に設定することができます。この場 合、 オ ブ
          ジェ クトを削除してキュー内のオブジェクト数を最大数より
          少なくしないかぎり、キューはフル状態であると見なされ ま
          す。

     qhp->splice(qtp);
          qhead::cut() による前回の操作の逆の操作を行います。ここ
          で、 qhp は cut() によって返されたポインタ、 qtp は qhp
          に対応する qtail オブジェクトを指すポインタです。 こ こ
          で、 これらの先頭および終端を指すポインタは、それぞれ別
          のキューに属しています。 splice() により、2 つの キュー
          が マー ジ さ れ、  qhp および qtp がそれぞれ指している
          qhead オブジェクトと qtail オブジェクトを削除し ま す。
          マージされたキューの中では、 qtp が指すキューのすべての
          オブジェクトは、 qhp が指すキューのどのオブジェクトより
          も 前に配置されます。この復元後のキューは再度、オリジナ
          ルの cut() が行われたオリジナルの qhead オブジェクト お
          よ び  qtail オブジェクトに対応づけられます。マージによ
          り、それまでフル状態であったキューがフル状態でなくな る
          場 合、または空のキューが空でなくなる場合、その状態を待
          機しているすべてのタスクに通知します (タスクは実行可 能
          になります)。 task(3C++) を参照。

     qtail *qtp = qh.tail();
          キューに対応する qtail オブジェクトを指すポインタを返し
          ます。 qtail が存在しない場合は新しく作成します。

  クラス qtail
     qtail qt(m, s);
          qtail オブジェクトと、それに対応するキューを作 成 し ま
          す。 新しいキューのモードは m 、最大のサイズは s に設定
          されます。モードおよびサイズのパラメタの結果に つ い て
          は、 上 記 を参照してください。メンバー関数 head() は、
          キューに対応する qhead オブジェクトを指すポインタを返し
          ます。

     objtype ot = qt.o_type();
          この仮想関数は、オブジェクトの種類を返します。 qtail の
          場合、オブジェクトの種類は QTAIL です。

     int ispending = qt.pending();
          この仮想関数は、対応するキューがフル状態であればゼロ 以
          外の値 (真) を、そうでなければゼロ (偽) を返します。

     qt.print(how);
          対応するキューについてのデータを stdout ( cout ではない
          )  に出力します。 int 型の第 1 引数 how の VERBOSE ビッ
          トがセットされていれば、キュー内のすべてのオブジェク ト
          に関する情報を出力します。第 2 引数は内部的に使用するも
          ので、デフォルトはゼロです。

     qtail *qtp = qt.cut();
          新しい qtail オブジェクトを作成してオリジナルのキューに
          追 加し、そのオブジェクトを指すポインタを返します。オリ
          ジナルの qtail ( qt ) を新しい空のキューを指すように 変
          更します。この新しいキューに対応する qhead を取り出す場
          合は、 qt.head() を使用してください。結果とし て、  qtp
          は オリジナルの qtail を指すようになり、 qhead はオリジ
          ナルのキューに対応したままです。つまり、次のような状 況
          になります。
          qtp->head()->get()
               オリジナル・キューの先頭の項目を取り出す。す な わ
               ち、 オリジナルの qhead はまだ、オリジナルのキュー
               から項目を取り出す。
          qtp->put(op)
               オリジナルのキューにオブジェクトを追加する。
          qt.head()->get()
               新しいキューに項目が登録 (追加) されていれば、その
               先頭の項目を返す。
          qt.put(op)
               新しいキューにオブジェクトを追加する。

          この方法により、そのキューのオリジナルの qhead や qtail
          を 使用し、コードを変更することなく既存のキューにフィル
          タを挿入することができます。フィルタは、オリジ ナ ル の
          qtail  を用いてキューに登録 (追加) されたオブジェクトを
          取り出すときには qtp->head()->get() の等価を使 用 し ま
          す。 また、オリジナルのキューにオブジェクトを追加する場
          合は qtp->put(op) を使用します。このようにして追加さ れ
          たオブジェクトは、 qhead を参照しているコードによって取
          り出されます。オリジナルのキューに対して追加や取り出 し
          を 行う既存のコードは、フィルタを通してオブジェクトを操
          作するようになります。キューは qtail::splice() によって
          復元できます。 qhead には cut と splice の 2 つの関数が
          対応づけられていますが、この 2 つの関数のペアは同じオブ
          ジェ クト ( qhead または qtail のどちらか) から使用しな
          ければなりません。

     qhead *qtp = qt.head();
          キューに対応する qhead を指すポインタを返します。 qhead
          が存在しない場合は新しく作成します。

     int ok = qt.put(op);
          qt に対応するキューがフル状態でなければ op が指す オ ブ
          ジェ ク ト をそのキューに追加し、値 1 (真) を返します。
          キューがフル状態であるとき、動作は qt のモードに依存 し
          ま す。モードが WMODE の場合、 put() を呼び出すタスクは
          キューがフル状態でなくなるまで中断されます。 モー ド が
          ZMODE の場合は直ちにゼロを返します。モードが EMODE の場
          合はランタイム・エラーが発生 し、  object::task_error()
          が呼び出されます。

     int i = qt.rdmax();
          対応するキューに入れることができるオブジェクトの (現 在
          の) 最大数を返します。

     qmodetype qm = qt.rdmode();
          qt の現在のモード (WMODE、EMODE、ZMODE のいずれか) を返
          します。

     int i = qt.rdspace();
          フル状態になる前に、対応するキューに追加できるオブ ジェ
          クトの数を返します。

     qt.setmode(qm);
          qt のモードを qm に設定します。 qm は、 WMODE、 EMODE、
          ZMODE のいずれかです。

     qt.setmax(max);
          対応するキューに入れることができる項目の最大数を max に
          設 定します。最大数は、キュー内の現在のオブジェクトの数
          より小さい値に設定することができます。この場 合、 オ ブ
          ジェ クトを削除してキュー内のオブジェクト数を最大数より
          少なくしないかぎり、キューはフル状態であると見なされ ま
          す。

     qtp->splice(qhp);
          qtail::cut() による前回の操作の逆の操作を行います。 qtp
          は cut() によって返されたポインタ、 qhp は qtp に対応す
          る qhead オブジェクトを指すポインタです。ここで、先頭お
          よ び終端を指すこれらのポインタは、それぞれ別のキューに
          属しています。 splice() により、2 つのキューがマージ さ
          れ、 qhp と qtp がそれぞれ指している qhead オブジェクト
          と qtail オブジェクトを削除します。マージされたキューの
          中では、 qtp が指すキューのすべてのオブジェクトは、 qhp
          が指すキューのどのオブジェクトよりも前に配置されま す。
          この復元後のキューは再度、オリジナルの cut() が行われた
          オリジナルの qhead オブジェクトと qtail オブジェクト に
          対 応づけられます。マージにより、それまでフル状態であっ
          たキューがフル状態でなくなる場合、または空のキューが 空
          で なくなる場合、その状態を待機しているすべてのタスクに
          通知されます (タスクは実行可能になります)。  task(3C++)
          を参照。


診断

     task(3C++) を参照してください。


関連項目

     task.intro(3C++), interrupt(3C++), task(3C++), tasksim(3C++)