(57)【要約】【課題】多数のスレッドを同時に実行するマルチスレッドプログラムにおいて、 スタック領域のために消費されるメモリ量を節約する。【解決手段】全スレッドに割り当てられる複数のスレッド個別スタック７と、 該個別スタックの数より少なく、前記スレッド間で共有される複数の共有スタック８を使用し、外部イベント待ちに至る可能性のあるスレッド（処理経路）では個別スタック７を使用し、それ以外のスレッドでは共有スタック８を使用することによりメモリ使用量を節約することを特徴とするマルチスレッドプログラム処理方法。【選択図】図１
2008102847.tif 000002
【特許請求の範囲】
【請求項１】
複数のスレッドに対し１対１の関係で複数のスレッド個別スタックを割り当て、
前記個別スタックの数より少なくかつ各のメモリサイズが各スレッド個別スタックのメモリサイズよりも大きい複数の共有スタックを設け、外部イベント待ちに至る可能性のあるスレッドでは前記スレッド個別スタックを使用し、それ以外のスレッドでは前記共有スタックを使用することにより前記複数の共有スタックを前記スレッド間で共有することを特徴とするマルチスレッドプログラム処理方法。
【請求項２】
複数のスレッド全てに対して１対１の関係で割り当てられる複数のスレッド個別スタックと、
前記個別スタックの数より少なくかつ各のメモリサイズが各スレッド個別スタックのメモリサイズよりも大きい複数の共有スタックと、
外部イベント待ちに至る可能性のあるスレッドでは前記スレッド個別スタックを使用し、それ以外のスレッドでは前記共有スタックを使用することにより前記複数の共有スタックを前記スレッド間で共有する処理手段と具備することを特徴とするマルチスレッドプログラム処理装置。
【請求項３】
請求項２または３において、前記処理手段は
スレッド管理部と、
スタック管理部と、
マルチスレッド型アプリケーションプログラムと、
該プログラムを実行するＣＰＵとからなり、
前記アプリケーションプログラムは前記スレッド管理部が提供するルーチンを用いてスレッドの生成と切り換えを行い現在実行中のスレッドがイベント待ち状態に入り、外部イベント源または内部イベント源から通知されるイベントに基いてスレッドを切り換え、前記スタック管理部が提供するルーチンを用いて前記スレッド個別スタックと前記共有スタックの間の切り換えを行うことを特徴とするマルチスレッドプログラム処理装置。
【請求項４】
請求項３において、前記処理手段は
ストリーム受信器と、
ストリームバッファと、
パターン検索器とを有し、
該ストリーム受信器は外部ネットワークから入力されるトラフィックからストリームを抽出しストリームバッファに保存し、前記ＣＰＵから特定ストリームに対する受信要求を受けると未通知の受信済みデータが存在するか否かを調べ、存在する場合は前記外部イベントとして前記ＣＰＵに通知し、未通知の受信済みデータが存在しない場合は次のデータを受信したとき前記外部イベントとしてＣＰＵに通知し、
前記ストリームバッファは前記ストリーム受信器が抽出したストリームを 保存し、特定ストリームのデータ読み出し範囲と転送先のメモリ領域を指定する読み出し要求を前記ＣＰＵから受けると該指定された範囲のデータを該転送先に転送し、前記内部イベントとして前記ＣＰＵに通知し、
前記パターン検索器は前記ＣＰＵから検索要求を受けると該検索要求が指定するストリーム、データ範囲、文字列パターンを検索キーとして前記ストリームバッファを検索し、
指定された文字列パターンが指定されたストリームの指定された範囲のデータ中に含まれている場合はその文字列パターンのバイト位置を検索結果通知として前記ＣＰＵに通知することを特徴とするマルチスレッドプログラム処理装置。
【発明の詳細な説明】
【技術分野】
【０００１】
本発明は、マルチスレッドプログラムにおけるスタック管理技術に関し、 特にスタック領域により消費されるメモリ量を節約する技術に関する。
【背景技術】
【０００２】
ソフトウェアのプログラム構成としてマルチスレッドが用いられることが多い。具体例としてネットワークのトラフィックを処理するアプリケーションは1つのセッション(またはフロー、ストリーム)に対して1つのスレッドを割り当て、1つのプロセッサ上で同時並行に実行する。マルチスレッドプログラムでは、同時に実行される全てのスレッドに対して個別のスタック領域が必要でありそのサイズはプログラムの構造によって異なる。
規模の大きなプログラムではスタック使用量が大きくなる傾向にあり、同時に実行するスレッド数が多くなるとスタック領域のためにメモリが圧迫される。 １つのセッションに１つのスレッドを割り当てると、より多くのセッションを同時に処理できるようにするためにはより多くのメモリが必要となる。この問題を解決するための従来技術として特許文献１がある。該従来技術はスレッド(タスク)実行時は共有スタックを使用しスリープするときに共有スタックの内容を別領域に退避することにより、メモリ使用量の効率化を計るものである。この方式の問題点は、スタック内の使用中の領域のサイズが増加するとスタック内の使用中領域のサイズが増加するとスタックの退避／復旧のためのメモリコピー時間も増加することであり、この方法を使わない場合に比べ性能が著しく劣化する恐れがある。
【特許文献１】特開2005-71141
【発明の開示】
【発明が解決しようとする課題】
【０００３】
本発明の目的は、多数のスレッドを同時に実行するマルチスレッドプログラムにおいて、スタック領域のために消費されるメインメモリ量の節約を可能とするマルチスレッドプログラム処理方法および装置を提供することである。
さらに、本発明の他の目的はメインメモリを用いてより多くのスレッドの同時実行を可能にするマルチスレッドプログラム処理方法および装置を提供することである。
【０００４】
さらに、本発明の他の目的は各共有スタックのメモリサイズを各スレッド個別スタックに比べて遙かに大きくすることによりプログラマーの注意力をスレッド個別スタックの使用量にのみ集中させ、これによりプログラマーの負担を軽減させるマルチスレッドプログラム処理方法および装置を提供することである。
【０００５】
さらに、本発明の他の目的はスタック使用量が増加しても性能低下が発生しないマルチスレッドプログラム処理方法および装置を提供することである。 
【課題を解決するための手段】
【０００６】
第一の観点に基づく本発明のマルチスレッドプログラム処理方法は複数のスレッドに対し１対１の関係で複数のスレッド個別スタックを割り当て、
前記個別スタックの数より少なくかつ各のメモリサイズが各スレッド個別スタックのメモリサイズよりも大きい複数の共有スタックを設け、外部イベント待ちに至る可能性のあるスレッドでは前記スレッド個別スタックを使用し、それ以外のスレッドでは前記共有スタックを使用することにより前記複数の共有スタックを前記スレッド間で共有することを特徴とする。
【０００７】
更に、第二の観点に基づく本発明のマルチスレッドプログラム処理装置は複数のスレッド全てに対して１対１の関係で割り当てられる複数のスレッド個別スタックと、前記個別スタックの数より少なくかつ各のメモリサイズが各スレッド個別スタックのメモリサイズよりも大きい複数の共有スタックと、外部イベント待ちに至る可能性のあるスレッドでは前記スレッド個別スタックを使用し、それ以外のスレッドでは前記共有スタックを使用することにより前記複数の共有スタックを前記スレッド間で共有する処理手段と具備することを特徴とする。
【発明の効果】
【０００８】
本発明の第１の効果は、外部イベント待ちに至る経路以外でのスタック領域の個数はスレッド数に比べて少数であるため、外部イベント待ち経路のスタック使用量を少なくすれば、全体としてスタック領域によるメモリ使用量を削減することができる。
【０００９】
第２の効果は、従来はスタック使用量節約のためプログラム全域に亘りスタックの使用状況に注意してプログラムを組む必要があったが、
本発明の方式では外部イベント待ち経路では個別スタックより数の少ない共有スタックを使用し、かつ1つの共有スタック領域のメモリサイズをスレッド個別スタックに比べて遙かに大きくすれば、プログラマはスレッド個別スタックを使用する処理においてのみスタック使用量にのみ注意すればよく、共有スタックの使用量に注意する必要がない。
【００１０】
第３の効果は、共有スタックを用いることによりスレッド個別スタックのためのメモリ使用量を小さくできるため、限られた量のメモリを用いてより多くのスレッドを同時に実行することが可能であり、殊にネットワーク処理を行うアプリケーションではより多くのセッションを同時に処理することが可能となる。
【００１１】
第４の効果は、 特許文献１のようにスタック内のデータを別領域へ退避させる必要がないためスタック使用量が増加してもメモリコピーによる性能低下が発生しない。
【発明を実施するための最良の形態】
【００１２】
図１は本発明の基本構成を示し、メインメモリ４に格納されアプリケーションプログラム１と、スレッド管理部２とスタック管理部３とからなり、該プログラムを実行するＣＰＵ５を含みアプリケーション実行環境を構成する。
【００１３】
アプリケーションプログラム１はスレッド管理部２が提供するルーチンを用いてスレッドの生成、切り換えを行うマルチスレッド型のプログラムである。現在実行中のスレッドがイベント待ち状態に入ったとき、外部イベント源１０または内部イベント源１１から通知されるイベントに基いてスレッドを切り換える。また、スタック管理部３が提供するルーチンを用いて複数のスレッド個別スタック７と該個別スタックの数より少ない複数の共有スタック８の間の切り換えを行う。
【００１４】
スレッド管理部２はスレッドの生成およびスレッドの切り換えを行い生成した各スレッドに対してスレッド管理情報６とスレッド個別スタック７の領域をメインメモリ４内に割り当てる。また、スレッド切り換え時には、現在実行中のスレッドのスレッド管理情報６の中にＣＰＵ５の現在のコンテキスト９を保存し、新しく実行するスレッドのスレッド管理情報６に保存されたコンテキスト９をＣＰＵ５にロードする。
【００１５】
スタック管理部３は共有スタック８の割当、解放及び個別スタック７と共有スタック８の切り換えを行う。このスタック切り換えは、現在のスタックポインタの内容をスレッド管理情報６の中に保存し、新しいスタックのアドレスをスタックポインタ（ＳＰ）にロードすることにより行なわれる。
【００１６】
スレッド管理情報６はスレッドごとに割り当てられる固定サイズの領域であり、この領域には、現在実行していない(待ち状態の)スレッドのコンテキスト９が保存される。また、ある共有スタック８を使用中のスレッドは該共有スタックに切り換える直前に指定していたスレッド個別スタック７のスタックポインタの内容を保存する。
【００１７】
外部イベント源１０は外部イベントを生成しアプリケーションプログラム１へ通知する。 外部イベントはシステム外部の要因により生成されるイベントであり、例えば、ネットワーク処理の場合は外部からのデータ受信が外部イベントとなる。
【００１８】
内部イベント源１１は内部イベントを生成しアプリケーションプログラム１へ通知する。内部イベントは、アプリケーションプログラム１が発行した処理要求に対して何らかの処理が行われた結果として生成されるイベントであり、アプリケーションプログラム１が処理要求を発行してから比較的短い所定時間内に必ず発生する。
【００１９】
スレッド個別スタック７と共有スタック８はプログラム１の実行に必要となる スタック領域であり、各領域は連続するアドレス空間の中に確保される。スレッド個別スタック７は１スレッドに１つずつ割当てられるスタック領域であり、同時に実行される可能性のあるスレッド数分だけ存在する。また、スレッド個別スタック７は外部イベント待ちに至る可能性のある処理経路（スレッド）において使用される。外部イベントはいつ発生するか分からないため、全スレッドが同時に外部イベント待ち状態に入る可能性がある。そのため、プログラムの最上位ルーチンから外部イベント待ち状態に至るまでの状態はスレッド個別スタック７に保存される。
【００２０】
共有スタック８は複数のスレッド間で共有されるスタック領域であり、その個数はスレッド数よりも少なく、各のサイズはスレッド個別スタック７よりも大きく、外部イベント待ちに至る可能性のない処理経路において使用される。 
上述のごとく、内部イベントはプログラム１が内部イベント源１１に対して処理要求を発行してから一定時間以内にイベント発生するためスレッドが最初に外部イベントを受けた後、内部イベント待ちを何回か行い再び外部イベント待ちに戻るまでの時間も一定時間以内である。これは、共有スタック８は割り当てられてから必ず一定時間以内に解放されることを意味する。また、同時に内部イベント待ち状態に入れるスレッド数は共有スタックの数に制限されることを意味する。
【００２１】
図２に示すごとく本システムのハードウェアはメインメモリを含むＣＰＵ２０、ストリーム受信器２１、ストリームバッファ２２、パターン検索器２３、ログストレージ２４とから構成される。ストリーム受信器２１は外部ネットワークから入力されるトラフィックからストリームを抽出しストリームバッファに保存する。
ＣＰＵ２０から特定ストリームに対する「受信要求」を受けると未通知の受信済みデータが存在するか否かを調べ、存在する場合「受信通知」（外部イベント）としてＣＰＵ２０に知らせる。
未通知の受信済みデータが存在しない場合は次のデータを受信してから受信通知をＣＰＵ２０に送る。
【００２２】
ストリームバッファ２２はストリーム受信器２１が抽出したストリームを 保存しＣＰＵ２０からの読み出し要求を受ける。該読み出し要求において、ＣＰＵ２０はストリームバッファ２２内の特定ストリームのデータ読み出し範囲と転送先のメモリ領域を指定する。ストリームバッファ２２は該読み出し要求が指定する範囲のデータを読み出し、これを指定されたメモリ領域に転送し、転送が終了すると「読出し完了通知（内部イベント）」をＣＰＵ２０に返送する。
【００２３】
パターン検索器２３はＣＰＵ２０から「検索要求」を受けると該検索要求が指定するストリーム、データ範囲、文字列パターンを検索キーとしてストリームバッファ２２を検索し、
指定された文字列パターンが指定されたストリームの指定された範囲のデータ中に含まれている場合はその文字列パターンのバイト位置を「検索結果通知」としてＣＰＵ２０に通知する。
【００２４】
ログストレージ２４はＣＰＵ２０から「ログ保存要求」を受けると該保存要求が指定するデータのログを保存する。本要求に対する応答はない。
【００２５】
ストリーム受信器に入力される各ストリームは連続する複数のメッセージからなり、各メッセージは1つのヘッダとそれに続く1つのボディから構成される。ボディ長はヘッダ内の特定のフィールドが指定する。
【００２６】
ＣＰＵ２０はマルチスレッドアプリケーションプログラム１に基づきストリーム受信部２１が受信したストリーム中の各メッセージの1行目を抽出しログストレージ２４に出力し１つのストリームに対して１つのスレッドを実行する。
【００２７】
図３はアプリケーションプログラム１の構成を示す。 楕円で示す部分は処理ルーチンを表わし、各楕円の中の文字列はルーチンの名称、
括弧内の数字はそのルーチンで使用するスタックのバイトサイズを示している。
【００２８】
各ルーチン間を結ぶ実線および破線の矢印はサブルーチン呼出しの関係を表 わしている。実線の矢印はスレッド個別スタック７を使用する処理経路におけるサブルーチン呼出しを示し、破線の矢印は共有スタック８を使用する処理経路におけるサブルーチン呼出しを示す。星印はサブルーチン呼出し時に個別スタック７から共有スタック８への切り換え、サブルーチンから呼出し元への復帰時に共有スタック８から個別スタック７への切り換えを行うポイントを示している。
以下に各処理ルーチンの概要を説明する。
【００２９】
ThreadMain 30はスレッドの最上位ルーチンでありHeaderProc 31を用いてヘッダ受信、ログ出力とボディ長の取得を１つのメッセージについて行った後、
BodyProc 32を用いてボディ全体を受信するまで待つ。この処理をストリームが終了するまで繰り返す。
【００３０】
HeaderProc 31はストリーム内の各メッセージのヘッダを受信し、その１行目をログストレージ２４へ出力し受信したヘッダからホディ長を検出する。
HeaderProc 31は最初にStrmRecvWait 33を用いて次のデータの受信を待ちEoHdrCheck 34を用いて過去に受信したデータを検査しヘッダ全体を受信し終わったか否かを判定する。まだヘッダ全体の受信が終わっていなければ再びStrmRecvWait 33を用いて次のデータの受信を待つ。ヘッダ全体を受信し終わったら、次にLogProc 35を用いてヘッダの1行目をログストレージ２４に格納する。最後に、BodyLenGet 36を用いてヘッダの中からボディ長を抽出する。
【００３１】
BodyProc 32はヘッダに続くホディ全体を受信し終えるまで待つ。
本ルーチンは最初にStrmRecvWait３３を継続して用いて次のデータを受信するのを待つ。 ボディの最後まで受信し終えたら処理終了する。
【００３２】
StrmRecvWait
33はストリームの次のデータを受信するまで待ちStrmRecvReq 37を用いてストリーム受信器２１に対して受信要求を発行し、次にEventWait 38を用いてストリーム受信器２１からの受信通知を待つ。
【００３３】
EventWait 38は次の外部イベントまたは内部イベントを検出するまで待ち
新しいイベントを検出したらスレッド管理部２のルーチンを使用してそのイベントに対応するスレッドに実行を切り替える。切り替え元のスレッドはそのスレッドに対応するイベントを検出するまでEventWait 38に留まる。本ルーチンはアプリケーションプログラム１において唯一スレッド切り替えを行う箇所である。現在実行中のスレッド以外のスレッドは初期状態を除いてEventWait３８に留まる。
【００３４】
EoHdrCheck 34は現在受信しているメッセージにおいてヘッダの最後、即ち空行が含まれているか否かを検査するルーチンである。本ルーチンはPattSearch３９を用いて受信済みストリームの中から空行を探す。
【００３５】
PattSearch３９は受信済みストリーム中の特定のバイト範囲のデータに特定のパターンが含まれているか否かを検査し、含まれている場合そのパターンのストリーム上のバイト位置を返信する。本ルーチンは、PattSearchReq４０を用いてパターン検索器２３に検索要求を発行し、EventWait４１を用いてパターン検索器２３からの検索結果通知を待つ。
【００３６】
BodyLenGet
36は受信したヘッダの中に格納されたボディ長を取得する。 最初にPattSearch３９を用いヘッダからボディ長を含むフィールドのバイト位置を検索し、次にStrmBuffRead４２を用いそのフィールド全体のデータをストリームバッファ２２からメインメモリの指定された場所に転送する。最後に、そのフィールドからボディ長を抽出する。なお、この転送を実行する際、StrmBuffRead４２はStrmBuffReadReq４３を用いストリームバッファ２２に読出し要求を発行し、EventWait 41を用いストリームバッファ２２からの読出し完了通知を待つ。
【００３７】
LogProc 35は受信済みヘッダの１行目をログストレージ２４に保存する。
本ルーチンは、最初にStrmBuffRead 42を用いヘッダの最初の特定バイト数の データをストリームバッファ２２からメインメモリに読み込み、LogWrite 44を用いログストレージ２４に対してログ書込み要求を発行しメインメモリ上で指定された前記データの先頭から最初の改行までを書き込む
。
【００３８】
図3のスタックは次のように切り替えられる。スレッド開始時、アプリケーションプログラム１はスレッド個別スタック７を使用して動作し図中の星印のサブルーチン呼出しの直前で共有スタックを割り当て、スタックポインタを割り当てた共有スタックに切り替える。また、該サブルーチンから呼出し元ルーチンに戻ってきた直後に共有スタック８から個別スタック７へスタックポインタを切り替え、該共有スタック８を解放する。
ここで、共有スタック８の割り当て、解放及びスタックポインタの切り替えはアプリケーションプログラム１がスタック管理部３からルーチンを呼出すことにより行われる。
【００３９】
スレッド切り替えポイント(図3の星印)はつぎのように決められる。アプリケーションプログラム１は外部イベント待ち、即ちストリーム受信待ち (図3のEventWait 38)に至る可能性のある処理経路上(図中の実線の矢印)ではスレッド個別スタック７を利用し、それ以外の処理経路上(図中の破線の矢印)では共有スタック８を使用する。
【００４０】
ストリームの受信はいつ発生するのか分からないため、 イベントが発生するまで長時間待たされる可能性がある。 そのため、実行中の全てのスレッドがストリーム受信待ち状態 (EventWait 38)に入る可能性がある。このため、スレッドの先頭(ThreadMain
30)から外部イベント待ち（EventWait 38）までのスタックの状態は全てのスレッドについて保存する必要がある。これが、スレッド個別スタック７を使用する理由である。
【００４１】
一方、パターン検索器２３による検索結果通知やストリームバッファ２２による読出し完了通知などの内部イベントは、処理要求を発行してから比較的短い時間内に必ず発生することが保証されているため、
これらのイベント待ち状態に同時に入るスレッド数は限られている。 このため、スレッド個別スタック７を使用する必要はなく領域の容量に余裕のある共有スタック８を使用する
。
【００４２】
イベント待ち以外でスレッド切り替えは行われないためいずれのイベント待ち状態にも到達しない処理経路上では領域の容量に余裕のある共有スタック８を使用する。
【００４３】
図４はスタックの切り換えを伴わない通常のサブルーチン呼出し時のスタックの変化の状態を示す。これは、図３で星印の付いていないサブルーチン呼出しに該当する。但し、スタックの使用方法は使用するＣＰＵ、ＯＳ、コンパイラなどに依存する。本実施例はその一例を示す。ＢＰ(ベースポインタ)とＳＰ(スタックポインタ)は、それぞれＣＰＵが持つレジスタであり、スタック領域内のアドレスを保持する。ＢＰは現在実行中のルーチンにおけるスタックフレームの底部を指し、相対参照を行う際のベースレジスタとして使用される。ＳＰは現在のスタックポインタであり、スタックへのプッシュ／ポップ操作が行われると参照／更新される。
各ルーチン内で使用する内部変数はスタックの中に確保されている。
【００４４】
(Ａ１)はサブルーチンを呼び出す前の呼出し元ルーチンにおけるスタックの状態を示している。
【００４５】
(Ａ２)はサブルーチンを呼び出す直前のスタックが引数を準備する状態を示す。即ち、サブルーチンを呼出す前、呼び出し元ルーチンは該サブルーチンに渡す引数をスタックにプッシュする。
【００４６】
(Ａ３)は前記サブルーチンを呼び出した直後のスタックの状態を示す。
前記サブルーチンを呼出した瞬間、呼出し元ルーチンにおけるプログラムの次の命令のアドレス(図中の戻りInstruction address Pointer)がスタックにプッシュされる。
【００４７】
(Ａ４)は呼出された前記サブルーチンにおいてスタックが初期化された後の状態を示す。各サブルーチンは呼出された直後、現在のベースポインタ（ＢＰ）の値をスタックにプッシュし、そのときのスタックポインタの値をＢＰに代入し、スタック内に内部変数に必要な領域を確保しその分だけスタックポインタの値を進める。
【００４８】
１つのサブルーチンの実行が終了し呼出し元に戻る過程は(Ａ５)、(Ａ６)、(Ａ７)の順にスタックの状態が変化する。
【００４９】
図5と図6はスタック切り換えを伴うサブルーチン呼出しにおけるスタックの状態の変化を示す。これは図3で星印の付いているサブルーチン呼出しに該当する。サブルーチンを呼出す前のスタックの状態は図4の(Ａ１)と同じである。
【００５０】
呼出し元ルーチンでは、サブルーチンを呼出す前にスタック管理部３のルーチンを用いて、共有スタック８の割り当てと個別スタック７から共有スタック８への切り換えを行なう。（Ｂ１）はこのときの状態を示す。具体的には、スタック管理部３が先ず現在のスタックポインタ（ＳＰ）が保持しているスタックのアドレスをスレッド管理情報６の変数ＯＳＰに保存する。次に、未使用の共有スタック８を実行中のスレッドに割り当て、ＳＰにその共有スタック８の底部アドレスをロードする。このときＳＰは共有スタックを指しているため、これ以降の処理はスタック切り換えを伴わないサブルーチン呼出しの場合と同一である。
【００５１】
(Ｂ２)はサブルーチンを呼び出す直前の個別スタック７と共有スタック８の状態を示している。
サブルーチンを呼出す前、呼び出し元ルーチンはサブルーチンに渡す引数を共有スタック８にプッシュする。
【００５２】
(Ｂ３)はサブルーチンを呼び出した直後の個別スタック７と共有スタック８の状態を示している。
サブルーチンを呼出した瞬間、呼出し元ルーチンにおけるプログラムの 次の命令のアドレス(図中の戻りIP)が、共有スタックにプッシュされる。
【００５３】
(Ｂ４)は呼出されたサブルーチンにおいて共有スタック８を初期化した後の
個別スタック７と共有スタック８の状態を示す。各ルーチンは呼出された直後、現在のＢＰの値をスタックにプッシュし、 そのときのＳＰの値をＢＰに代入し、共有スタック８内に内部変数に必要な領域を確保しその分だけＳＰを進める。
【００５４】
サブルーチンの実行が終了し呼出し元に戻る過程で個別スタックと共有スタックの状態は (Ｂ５)、(Ｂ６)、(Ｂ７)の順に変化する。
【００５５】
最後に、スタック管理部３のルーチンを用いて、共有スタック８から個別スタック７への復旧と共有スタック８の解放を行う。個別スタック７への復旧はスレッド管理情報６の変数ＯＳＰに保存された個別スタック７のアドレスをＳＰにロードすることで行われる。
【００５６】
図7は図3のプログラムをマルチスレッドで実行しているときのある瞬間における各スレッドにおけるスタックの状態を示している。図の上段は共有スタック８、下段はスレッド個別スタック７を示している。各スタックの図にそのスタックを使用しているルーチン名と括弧内にそのルーチンが消費しているスタックのバイト数を示す。
【００５７】
スレッド＃１はThreadMain 30、HeaderProc 31、LogProc 35の各ルーチンを経由してLogWrite 44を現在実行中である。最初はスレッド個別スタック７を使用し、LogProc
35を呼び出す時点で共有スタック８を使用する。
【００５８】
スレッド＃２はThreadMain 30、HeaderProc 31、BodyLenGet 36、PattSearch 39の各ルーチ ンを経由し、現在EventWait 41で内部イベント待ち状態にある。最初は個別スタック７を使用しBodyLenGet 36を呼び出す時点で共有スタック８を使用する。
【００５９】
スレッド＃３はThreadMain 30、HeaderProc 31、EoHdrCheck 34、PattSearch 39の各ルーチ ンを経由し、現在EventWait 41で内部イベント待ち状態にある。最初は個別スタック７を使用しEoHdrCheckを呼び出す時点で共有スタック８を使用する。
【００６０】
スレッド＃４はThreadMain 30、BodyProc 32、StrmRecvWait 33の各ルーチンを経由し、現在EventWait 38で外部イベント待ち状態にあり、個別スタック７を使用している。
【００６１】
スレッド＃５はThreadMain 30、HeaderProc 31、StrmRecvWait 33の各ルーチンを経由し
現在EventWait 38で外部イベント待ち状態にあり、個別スタック７を使用している。
【００６２】
なお、ここに示したスレッド以外にもスレッドが存在するかも知れないが、 現在実行中のスレッドはスレッド1のみであり、他のスレッドは内部イベント 待ちまたは外部イベント待ちの状態である。
【００６３】
図3と図7を用いて、本発明の方式を用いることでタック領域に必要なメモリ量を削減できることを説明する。
【００６４】
最初に、通常の方式に従いスレッド個別スタック７のみを使用する場合を考える。図3のプログラムにおいてスタック領域を最も大量に使用する処理経路 はThreadMain
30、HeaderProc 31、LogProc 35、StrmBuffRead 42を経由してEventWait 41に至る場合であり、272バイトが消費される。即ち、1つのスレッドに対して個別スタック７のために272バイト以上のメモリ領域を確保するため、同時スレッド数をＮとすると、272×Ｎバイト以上のメモリが必要となる。
【００６５】
次に、図3において個別スタック７と共有スタック８を使用する場合を考える。
スレッド固有スタック７の領域を最も大量に使用する処理経路は、Thread Main 30、HeaderProc 31、StrmRecvWait 33を経由しEventWait 38に至る場合とThreadMain 30、BodyProc 32、StrmRecvWait 33を経由しEventWait 38に至る場合であり、160バイトが使用される。また、共有スタック８の領域を最も大量に使用する処理経路はLogProc 35、StrmBuffRead 42を経由してEventWait 41に至る場合であり、192バイトが使用される。同時スレッド数をＮ、共有スタックの数をＭとすると、160×Ｎ＋192×Ｍバイト以上のメモリが必要になる。
【００６６】
上記従来例（特許文献１）との比較から、本発明のスレッド数Ｎが共有スタック数（Ｍ）の1.8倍以上であれば従来例よりメモリ消費量を少なくすることができる。
【図面の簡単な説明】
【００６７】
【図１】本発明のアプリケーション実行環境の基本構成図
【図２】本発明のハードウェア構成と入力データ形式を示す図
【図３】本発明のマルチスレッドアプリケーションプログラムの構成図
【図４】スタックの切り換えを伴わないサブルーチン呼出しのスタックの変化を示す図
【図５】スタックの切り換えを伴うサブルーチン呼出しのスタックの変化の一部を示す図
【図６】スタックの切り換えを伴うサブルーチン呼出しのスタックの変化のその他の部を示す図
【図７】図３のマルチスレッドプログラムを実行中の各スレッドのスタックの状態を示す図
【符号の説明】
【００６８】
１  アプリケーションプログラム
２  スレッド管理部
３  スタック管理部
４  メインメモリ
５  ＣＰＵ
６  スレッド管理情報
７  スレッド個別スタック
８  共有スタック
１０  外部イベント
１１  内部イベント
２１  ストリーム受信部
２２  ストリームバッファ
２３  パターン検索器
２４  ログストレージ
【図１】
2008102847.tif 000003
【図２】
2008102847.tif 000004
【図３】
2008102847.tif 000005
【図４】
2008102847.tif 000006
【図５】
2008102847.tif 000007
【図６】
2008102847.tif 000008
【図７】
2008102847.tif 000009