# マニュアルページ 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++)