class TJThread
スレッドをカプセル化するためのクラス
Public メンバ
- typedef void* ID
- スレッド識別子の型
- static const ID None
- スレッド識別子とはなり得ない定数
- static const int JOINDETACHED
- join() の例外的な戻り値
- static const int JOINTIMEOUT
- join() の例外的な戻り値
- static const int MIN_PRIORITY
- スレッド優先度の最小値
- static const int MAX_PRIORITY
- スレッド優先度の最大値
- static const unsigned DEFSTACKSIZE
- スレッドのデフォルトスタックサイズ(16kB)
Public メソッド
- TJThread(unsigned stacksize = DEFSTACKSIZE)
- TJThread オブジェクトを作成する
- TJThread(const char* name, unsigned stacksize = DEFSTACKSIZE)
- TJThread オブジェクトを作成する
- TJThread(TJRunnable* target, unsigned stacksize = DEFSTACKSIZE)
- TJThread オブジェクトを作成する
- TJThread(TJRunnable* target, const char* name, unsigned stacksize = DEFSTACKSIZE)
- TJThread オブジェクトを作成する
- void setPriority(int pri)
- スレッドのプライオリティを設定する
- int getPriority() const
- スレッドのプライオリティを取得する
- virtual void setJoinable(bool on)
- Joinable スレッドの状態に設定する
- virtual bool isJoinable() const
- Joinable スレッドならば true を返す
- virtual void start()
- スレッドの実行を開始する
- virtual void run()
- スレッド本体
- int join()
- スレッド終了を待ち合わせる
- int join(long milliseconds)
- タイムアウトを指定してスレッド終了を待ち合わせる
- static void exit(int code)
- カレントスレッドを終了させる
- static void sleep(long milliseconds)
- カレントスレッドを指定時間休止させる
- static void yield()
- カレントスレッドのCPUを一時的に放棄する
- void setName(const char* name)
- スレッド名を設定する
- const char* getName() const
- スレッド名を返す
- bool isAlive() const
- run() の中を実行中ならば true を返す
- static int activeCount()
- スレッド数を返す
- virtual ID getThreadID() const
- スレッド識別子を返す
- static TJThread* getThread(ID tid)
- スレッド識別子からスレッドオブジェクトのポインタを得る
- static ID currentThreadID()
- カレントスレッドのスレッド識別子を返す
- static TJThread* currentThread()
- カレントスレッドオブジェクトのポインタを返す
- static const char* currentThreadName()
- カレントスレッドの名前を返す
- () void putData(void* anydata)
- アプリケーションデータをスレッドに記憶する
- void* getData() const
- スレッドごとの情報を返却する
文書
スレッドをカプセル化するためのクラス.ThreadJack では,複数のスレッドを並行動作させることができる. このクラスはスレッドの作成・消去やスレッドに対する操作をカプセル化している.
ThreadJack では, スレッドによって実行されるプログラムの実装方法には, 以下の 2つがある.
1. TJThread をサブクラス化し,run() をオーバーライドする.
2. TJRunnable をサブクラス化し,run() をオーバーライドする.
それぞれの実行方法は,次の通り. いずれの場合も TJThread またはそのサブクラスのオブジェクトが必要である.
* (1) TJThread のサブクラスのオブジェクトを作成 * * class MyThread : public TJThread { * ・・・・ * public: * MyThread(const char* name) : TJThread(name) { } * ・・・・ * void run() { * ・・・・ // override TJThread::run() * } * }; * * MyThread* thread = new MyThread("myname"); * thread->start(); * ......... * thread->join(); // 必要であれば終了待ち合わせ * // スレッドオブジェクトは delete してはならない * * (2) TJRunnable の実装クラスのオブジェクトを引数にして * TJThread オブジェクトを作成 * * class MyRunnable : public TJRunnable { * ・・・・ * public: * ・・・・ * void run() { * ・・・・ // implement TJRunnable::run() * } * }; * * MyRunnable* runnable = new MyRunnable; * TJThread* thread = new TJThread(runnable, "myname"); * thread->start(); * ......... * thread->join(); // 必要であれば終了待ち合わせ * // スレッドオブジェクトは delete してはならない * *(2)の使用法は,1つの TJRunnable オブジェクトを複数の TJThread オブジェクト で共用できる,という利点がある.
TJThread は java.lang.Thread に似ているが java とはメモリ管理方法 が異なるためスレッドオブジェクトの作成と消去に次の注意が必要になる.
* ◆スレッドオブジェクトは必ず new 演算子によりヒープ領域に確保すること. * ◆スレッドオブジェクトはアプリケーションが delete しないこと. *あるスレッドが新たに別のスレッドを生成した場合, 生成元のスレッドを親スレッド,生成されたスレッドを子スレッドと呼ぶ.
[スレッドの状態とシステムの終了]
ANSI/ISO C++ により規定される int main() というエントリポイント に最初に入るスレッドを, 特に「main スレッド」と呼び,アプリケーション が TJThread クラスのインスタンスとして生成したスレッドと必要に応じて 区別することがある.
main スレッド以外のスレッドでは,スレッドの実行プログラムは TJThread もしくは TJRunnable の run() メソッドの実装として表現される.
スレッドが run() を実行中の時,そのスレッドは alive であるという. run() から復帰するか,または明示的に TJThread::exit(int) をよびだすこと で run() は終了し,alive 状態から非 alive 状態へと遷移する. スレッドの終了コードは,run() から自然に復帰した場合は0 となり, TJThread::exit(int) を呼び出した場合は引数が終了コードとなる. この終了コードは他のスレッドが TJThread::join で受け取ることができる.
main スレッドも,TJThread::exit(int) を呼び出すことができる.この場合も main スレッドが非 alive 状態となる.
ThreadJack に於けるシステム(プロセス)の終了は,次のどれかが起こった 時である.
* * 1. main スレッドが main からの復帰(return)した時. * (ただしTJThread::exit()呼び出しは復帰と見なさない) * 2. あるスレッド(main 以外でもよい)が大域のシステム終了(プロセス終了) * を引き起こす呼び出し(ANSI/ISO C++ では ::exit() もしくは ::abort()) * を呼び出した時. * 3. 全スレッドが非 alive となった時. * *また,ThreadJack では プロセスのコピーを行うシステム動作 (UNIX の fork, Win32 の CreateProcess)に対しての動作は未定義である. (将来の拡張項目とする)
[プライオリティ]
すべてのスレッドはプライオリティを持つ.一般に, プライオリティの高い スレッドはプライオリティの低いスレッドに優先して実行される. ただし,プライオリティがスケジューリングに与える正確な影響は システム依存である.
プライオリティの数値は Java と同じ仕様とする.プライオリティは そのスレッドを生成したスレッドから継承され setPriority() により 変更できる.
プライオリティは,スレッドの親子関係の中で継承される.すなわち, 新たに生成されたスレッドのプライオリティの初期値は親スレッドの プライオリティと同じ値である.
[待ち合わせ性]
スレッドオブジェクトに対するjoin()の呼び出しによって,他のスレッド がその終了を待ち合わせることができる. この性質を待ち合わせ性(joinability)という. しかし,作成したスレッドの終了に関心がない場合,意識的に待ち合わせ を省略することも可能である.
* (a) 作成したスレッドの終了に関心がある場合 * MyThread* t = new MyThread("myname"); * t->start(); // joinable なスレッド * ・・・ * int exitcode = t->join(); * * (b) 作成したスレッドの終了に関心がない場合 * FreeThread* t = new FreeThread("myname"); * t->setJoinable(false); // 非 joinable なスレッド * t->start(); * // これ以降,t の実行状態はこのスレッドから切り離される. * // [警告] これ以後の *t のアクセスは一般に危険 *ここで (a) では作成されたスレッドが終了したとき join() が復帰し戻り値に exit() の引数が返される. それに対して (b) では作成されたスレッドとの関わ り合いは一切ない. 作成したスレッドの終了状態や終了のタイミングを知る必要 がない場合にはこの方法は都合がよい.ただし,joinable なスレッドは必ず join する必要があり,逆に 非 joinable なスレッドは決して join してはいけない.
新規作成されたスレッドの待ち合わせ性は必ず joinable であり, 待ち合わせ性 は子スレッドに継承されることはない. setJoinable(false) の操作を受けたスレッドだけが 非joinable となる. 非 joinable スレッドを join() した場合の動作は不定である. joinable か どうかは setJoinable(bool) により変更可能であるが main スレッドだけは変更 できず, 必ず非 joinable である.
待ち合わせ性は,java.lang.Thread の Deamon 性とは無関係の属性であること に注意.
[その他]
スレッドは名前を持つ.名前は必ずしも全スレッドを通して一意ではない. 名前を指定せずに生成したスレッドには,適当な名前が付与される.
java.lang.Thread は java.lang.Runnable を implements しているが, ThreadJack では2つのクラスTJThread と TJRunnable には継承関係を 持たせていない.
TJThread のサブクラスを作る場合,そのクラスのデストラクタを protected と することを推奨する. これにより,スレッドを自動変数として生成したり, delete を直接呼び出すといったバグをコンパイル時に発見できる.
カレントスレッド以外のスレッドを強制終了させる機能(いわゆるキャンセル)は 提供しない. これを提供するとプログラマはキャンセルからの保護を検討しなけ ればならなくなる. java.lang.Thread の suspend, stop, resume は提供しない.
スレッドクラスのオブジェクトを扱う場合,特に this オブジェクトに対する 操作とカレントスレッドに対する操作の混乱が起こりやすいので注意が必要である. このクラスの主な public メソッドは以下のように分類される.
* [A] インスタンスメソッド -- this オブジェクトに対する操作 * void setPriority(int) * int getPriority() * void setJoinable(bool) * bool isJoinable() * bool isAlive() * void setName(const char*) * const char* getName() * TJThread::ID getThreadID() * [B] クラスメソッド -- クラス全体の操作 * TJThread* getThread(TJThread::ID) * int activeCount() * [C] カレントスレッドに対する操作 * void exit(int) * void sleep(long) * void yield() * TJThread::ID currentThreadID() * TJThread* currentThread() * const char* currentThreadName() * [D] 親スレッドの立場での子スレッドに対する操作 * TJThread( ... ) * void start() * int join() * int join(long) * [E] 通常はユーザが直接呼び出すことの無い操作 * void run() *特に注意すべき点は [C] のカレントスレッドに対する操作である. これらは すべて static であるため形式的にはクラスメソッドであるがカレントスレッド という特定のスレッドに対する操作である.
スレッドの識別情報としてスレッド識別子(ID)とスレッドオブジェクトへの ポインタが考えられる. 前者は効率的に実装できるが,後者のは一般に 内部的なクラスロックを必要とするため, 非効率である. したがってスレッドの識別のみ必要ならスレッド識別子を使うべきである.
- typedef void* ID
- スレッド識別子の型
- static const ID None
- スレッド識別子とはなり得ない定数
- static const int JOINDETACHED
- join() の例外的な戻り値.
意味 -- 非 joinable なスレッドを join() しようとした. JOINABLE ではないスレッドを join() した場合の動作は不定である. もしタイミングにより暴走をまぬがれた場合はこの値が戻される. この値は便宜上のものであり,アプリケーションはこの値を使った コードを書いてはならない. 値は,INT_MAX
- static const int JOINTIMEOUT
- join() の例外的な戻り値.
意味 -- タイムアウト値指定の join() でタイムアウトした. 値は,INT_MAX-1
- static const int MIN_PRIORITY
- スレッド優先度の最小値
- static const int MAX_PRIORITY
- スレッド優先度の最大値
- static const unsigned DEFSTACKSIZE
- スレッドのデフォルトスタックサイズ(16kB)
- enum Kind
- スレッドの種別
- TJThread(unsigned stacksize = DEFSTACKSIZE)
- TJThread オブジェクトを作成する.
- パラメータ:
- stacksize - スタックサイズ
- TJThread(const char* name, unsigned stacksize = DEFSTACKSIZE)
- TJThread オブジェクトを作成する.
- パラメータ:
- name - スレッド名
stacksize - スタックサイズ
- TJThread(TJRunnable* target, unsigned stacksize = DEFSTACKSIZE)
- TJThread オブジェクトを作成する.
- パラメータ:
- target - TJRunnable の実装クラスのオブジェクト
stacksize - スタックサイズ
- TJThread(TJRunnable* target, const char* name, unsigned stacksize = DEFSTACKSIZE)
- TJThread オブジェクトを作成する.
- パラメータ:
- target - TJRunnable の実装クラスのオブジェクト
name - スレッド名
stacksize - スタックサイズ
- virtual ~TJThread()
- TJThread オブジェクトを消去する.
TJThread のサブクラスでもデストラクタを protected にすること を推奨する.(スレッドオブジェクトのスタック上に確保や, delete 呼び出しの禁止)
- 参照 :
- join()
- void setPriority(int pri)
- スレッドのプライオリティを設定する. スレッドのプライオリティは Java と同じ仕様を採用する.
- パラメータ:
- pri - 優先度
- int getPriority() const
- スレッドのプライオリティを取得する. スレッドのプライオリティは Java と同じ仕様を採用する.
- 返す値 :
- プライオリティ
- virtual void setJoinable(bool on)
- Joinable スレッドの状態に設定する
- virtual bool isJoinable() const
- Joinable スレッドならば true を返す
- virtual void start()
- スレッドの実行を開始する
- virtual void run()
- スレッド本体.
このメソッドはライブラリが呼び出すスレッドのエントリポイントで あり, ユーザが呼び出すことは無意味である.
- int join()
- スレッド終了を待ち合わせる.
TJThread::exit によって返されるコードを受け取ることができる. joinable ではないスレッドに対して join() を実行した場合の動作 は不定である.
- 返す値 :
- スレッド終了コード
- 参照 :
- exit()
- int join(long milliseconds)
- タイムアウトを指定してスレッド終了を待ち合わせる.
TJThread::exit によって返されるコードを受け取ることができる.
- 返す値 :
- スレッド終了コード TJThread::JOINTIMEOUT タイムアウト
- パラメータ:
- milliseconds - ミリ秒
- 参照 :
- exit()
- static void exit(int code)
- カレントスレッドを終了させる.
- パラメータ:
- code - スレッド終了コード
- 参照 :
- join()
スレッド終了コードとして
TJThread::JOINDETACHED, TJThread::JOINTIMEOUT
は予約されているので使わないこと.
- static void sleep(long milliseconds)
- カレントスレッドを指定時間休止させる.
- パラメータ:
- milliseconds - ミリ秒
- static void yield()
- カレントスレッドのCPUを一時的に放棄する. 一時的に実行を他のスレッドに譲る.
- void setName(const char* name)
- スレッド名を設定する.
ただしスレッド名の一意性はこのメソッドでは保証されない.
- パラメータ:
- name - スレッド名
- const char* getName() const
- スレッド名を返す.
- 返す値 :
- スレッド名
- bool isAlive() const
- run() の中を実行中ならば true を返す.
- 返す値 :
- run()実行中なら true
- static int activeCount()
- スレッド数を返す.
- 返す値 :
- スレッド数
- virtual ID getThreadID() const
- スレッド識別子を返す
- static TJThread* getThread(ID tid)
- スレッド識別子からスレッドオブジェクトのポインタを得る
- パラメータ:
- tid - スレッド識別子
- static ID currentThreadID()
- カレントスレッドのスレッド識別子を返す
- static TJThread* currentThread()
- カレントスレッドオブジェクトのポインタを返す
- static const char* currentThreadName()
- カレントスレッドの名前を返す
- () void putData(void* anydata)
- アプリケーションデータをスレッドに記憶する.
このデータはスレッド毎に保持できる. 通常はスタックがあればスレッドごとの情報を記憶できるがスタックで はメソッドから復帰すると消滅する. スレッドごとに, かつメソッドから復帰しても保存されるデータを管理 したい場合にこの機能が使える. 管理されるデータの寿命についてはアプリケーションの責任である.
- 子クラスは存在しません
- 作者 :
- Susumu TOKUI @date 1998,6/20
索引(アルファベット順) HTMLクラス継承 または Java
This page was generated with the help of DOC++.