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