cloneのスタック管理方法の検討とpthread_create()のスタック管理について

このQ&Aのポイント
  • cloneのスタック管理方法を検討中です。現在は、malloc()でスレッド用のスタックエリアを確保し、アドレスをcloneのパラメータとして渡す方法と、calloc()でスタックエリアを確保し、インデックス値をcloneのパラメータとして渡す方法を検討しています。
  • pthread_create()の場合は、スタックの管理方法について詳細を知りたいです。
  • Linuxでのスレッドについて詳しいHPや参考書などを教えてください。
回答を見る
  • ベストアンサー

cloneのスタック管理

cloneのパラメータでスタックのアドレスを渡しますがその際のスタック管理で良い方法はないでしょうか? 条件: 1.cloneで生成されるスレッドは多数存在する。 2.各スレッドは不定期に消滅する。 3.他のスレッドからも消滅させられる。 現在以下の2つのパターンで検討していますが、他に良い方法はないでしょうか? 1.生成される度にmalloc()でスレッド用のスタックエリアを確保し、そのアドレスをcloneのパラメータとして渡す。消滅時にそのパラメータを使用しfree()で解放する。(但し、他のスレッドから消滅させられる場合にスタックのアドレスが分からない。) 2.生成されると思われる個数分のスタックエリアをcalloc()で確保し、そのインデックス値をcloneのパラメータとして渡す。消滅時にそのパラメータを使用しスタックエリアをクリアし次にcloneで生成されるスレッド用として使用する。(但し、他のスレッドから消滅させられる場合にスタックのインデックス値が分からない。) pthread_create()の場合、スタックの管理はどうなっているのでしょうか? Linuxでのスレッドについて詳しいHP、参考書等知っていれば教えて下さい。

  • zukka
  • お礼率100% (5/5)

質問者が選んだベストアンサー

  • ベストアンサー
  • kaz-sugi
  • ベストアンサー率50% (3/6)
回答No.1

ちょっと探してみたのですが、時間がなくてLinuxのpthreadライブラリの ソースは見つけられなかったです。。。 探して見てみるのが一番です。 多分、pthread側ではあまり考えずに、mmapかなにかでメモリ割り当て していると思います。。。 ちゃんとしたPOSIXスレッドなら、スレッドそのものが使いまわされる ので、いちいちpthread_createで毎回スレッドが作られるわけじゃ ないですしね。 つまり、スタックの割り当て・解放もそう頻繁には起きないです。 以下は、ご参考レベルで私の意見を述べます。 試してみていないので、ほんとにご参考・ヒントのレベルです。。。。 cloneプロセスが外部から終了させられる、、というのは、 シグナル等の非同期な手段で終了させているのでしょうか? そうであるなら、SIGHUPかなにかで終了させるようにし、 シグナルを受けた終了すべきプロセスでは、すぐに終了せずに、 シグナルハンドラへ飛んでから自分でスタックを開放してから終了する、、 あるいは、「終了したよ」という印を共有メモリに書きこんで それを監視するプロセスにより、メモリ解放・再割り当てを 行うようにしてはどうでしょうか? 例えば、 使用中/未使用のフラグ、 cloneプロセスの状態(生きてるよ、終了したよ)などのフラグや、 そのcloneプロセスが使用するスタックのアドレスなどを 格納する構造体を作成し、それを、cloneプロセスの 最大数分の配列にし、独自のcloneプロセス管理テーブルとする。 cloneでプロセスを作成して関数コールをする際に、引数を 渡せますが、そこのなかに自分で管理した未使用のIDを付与するようにして、 cloneされたプロセスは、そのIDをキーにして、管理テーブルを 参照更新するようにする。。。 cloneプロセス作成前に、割り当てられたIDから管理テーブルを 見つけ、スタックのアドレスが入っていなければ、mallocをして そこにアドレスを入れ、アドレスが入っていれば、それをそのまま使い、 使用中フラグをたててから、cloneする。cloneプロセスにはそのIDを渡す。。。 mallocに失敗したら、未使用テーブルのスタックを解放して メモリを確保する、あるいは定期的にテーブルを走査して 未使用のスタックを解放する、、などの方法もありますね。。。 ところで、pthread使うのはヤなんですか?

zukka
質問者

お礼

ありがとうございました。 アドバイスのようにアドレス管理テーブルを持って対処する方法でいきます。 pthreadを使うのはイヤでは無いのですが、 詳しい使用方法が載っている参考書等が手元になくcloneを先に検討しました。。 pthreadの使い方が分かりやすく載っている参考書、HPなどが有れば教えていただきたいです。お願いします。

その他の回答 (1)

  • kaz-sugi
  • ベストアンサー率50% (3/6)
回答No.2

たまたまみつけたのですが、下に紹介しますIBMのページの日本語記事一覧の中に 「POSIXスレッドの説明」というのが第3回まで連載しているようです。。。 ちらっと見ただけですが、けっこう詳しく書いてますね。 この中で、書籍等の説明もしているようです。

参考URL:
http://www-6.ibm.com/jp/developerworks/linux/library.html
zukka
質問者

お礼

ありがとうございます。 参考にし勉強します。 分からないことが有ったら、またアドバイスお願いします。。

関連するQ&A

  • pthread_detach

    先日、C,C++カテゴリで質問していたのですが回答がつきませんでしたので、こちらで質問させていただきます。 pthread_create()してpthread_detachしているとします。 pthread_create()する前にmallocで領域確保した変数を引数として生成スレッドに渡しているとすると、detachした時点でmallocで確保した領域はfree()されるのでしょうか? それともメモリリークとなりますか?

  • C++におけるスレッド制御に関して

    C++初心者です。 スレッド制御の勉強をしておりますが、 なかなかうまくいきません。 下記のソースのようにスレッド生成をしておりますが、 スレッド用メソッドには、*を付けて使用するしか方法はないのでしょうか? pthread_createに渡す第3パラメータをメソッド名のみにして、呼ばれ元のメソッドの戻り値をvoid* ではなく、void のみで実施したいと思っておりますが、方法がわかりません。 大変申し訳ございませんが、ご教授よろしくお願いいたします。 ############################################################## # pthread_test.cc ############################################################## #include <stdio.h> #include <pthread.h> #include <stdlib.h> #include <unistd.h> /* * スレッドパラメータ格納用 */ typedef struct {  char printVal;  int interval; } ThreadParamT; // スレッドイニシャル関数 void *ThreadTest(void *arg) {  ThreadParamT *thread_test_param =(ThreadParamT*)arg;  while(1) {   fprintf(stderr,"%c", thread_test_param->printVal);   sleep(thread_test_param->interval);  }  return NULL; } int main(int argc,char *argv[]) {  int status;  // スレッドのパラメータ  pthread_t thread_test;  ThreadParamT thread_test_param;  thread_test_param.printVal = 'a';  thread_test_param.interval = 1;  // スレッドを生成  status=pthread_create(&thread_test, NULL, ThreadTest, &thread_test_param);  if(status!=0){   fprintf(stderr,"ERR! OUT!\n");   exit(1);  }  // 10s間待つ  sleep(10);  fprintf(stderr, "\n");  return 0; } ##############################################################

  • H8マイコン スタック領域について

    スタック領域について教えて下さい。 [動作環境]  開発環境:ルネサス HEW Version 4.08  マイコン:ルネサス H8/1653  コンパイラ:H8SX,H8S,H8ファミリ用C/C++コンパイラパッケージ V7.00 HEWにて新規作成しますと、セクション定義にスタック領域(S)のアドレスと stacksct.h 内に スタック領域のサイズ #pragma stacksize 0x200 が自動で生成されると思います。 しかし、入手したH8/1653用のサンプルには #pragma stacksize のような サイズ指定がありませんでした。 [サンプル] (1)セクション定義やスタック領域のサイズ指定が無い (2)サブコマンドファイル(xxxx.sub)内でアドレスは設定されているが サイズの設定が無い。 -- サブコマンドファイル(xxxx.sub)-- START  CStart/00000000; START  P,C,D/00000400; START  B,R/00FF2000; START S/00FFC000; [質問]  質問1   (1)のスタック領域はどこに配置されるのでしょうか?  質問2   (2)のスタック領域は 00FFC000 を基準にどう確保   されるのでしょうか? (a)の方向へ確保?(b)の方向へ確保?          00F00000 (a)         ↑       00FFC000 (設定アドレス)         ↓       00FFFFFF (b)        質問3   (1)、(2)共にスタック領域と同時にヒープ領域も指定がありません。   これらは指定しなくても問題ないものなのでしょうか?   また、熟練者の方は指定しないものなのでしょうか? よろしくおねがいします。

  • スレッド

    スレッドを生成し、データのやり取りを行うプログラムを作成しようとしているのですが、使用関数が分かりません。 どなたか、ご存知でしたら、お教えください。 スレッドの作成関数はpthread_createを使うことは分かりました。 そこからデータを送る、受けるのやり方がわかりません。 プログラムの流れ スレッドを生成し、スレッドにデータを送る。 そのスレッド内で、データを調べ期待値だったらACK、 それ以外だったら、errorを返すといった感じです。 まだスレッドに関して知識が薄い為、質問も分かりづらいと思いますが、宜しくお願い致します。

  • スレッド制御に関して

    C言語の初心者です。 現在、スレッドの勉強をしております。 最近、pthreadをなんとなく理解しつつありますが、 下記の2点に関して試行錯誤しております。 (1)スレッドを周期的に起動したい (2)時間によって起動したい (1)は、例えば30秒毎にスレッドを起動させたい等といった、周期スレッドの生成方法です。今考えているのは、スレッドを生成後、スレッド生成元で30秒間sleepして、2回目のスレッドを起動…。といったイメージを考えております。 (2)に関しても同様で、例えば12時00分00秒にスレッドを生成したいというパターンで、スレッド生成元にて、時間を取得して、その時間が12時00分00秒であればスレッド生成を行うといったイメージを考えております。 上記2案とも初心者なりに考えた案なのですが、他によい案はありませんでしょうか? ご教授頂けますようよろしくお願いいたします。

  • .NET(C#)でのスタックオーバーフロー回避方法

    ASP.NET初心者です。初めて質問させていただきます。 ASP.NET(C#)でwin32系の外部ライブラリを使用したいのですが、そのライブラリを読み込むところで スタックオーバーフローが発生してしまいます。 同じライブラリをWindowsアプリケーション(C#)で使用したところ問題なく実行できました。 ASP.NETで同じように使用しようとするとスタックオーバーフローが発生してしまう状態です。 [デバッグ中のエラーメッセージ] xxxx.dllを読み込めません。再帰が深すぎます。スタックがオーバーフローしました。 [イベントログ] 障害が発生しているアプリケーション名: w3wp.exe、バージョン: 7.5.7600.16385、タイム スタンプ: 0x4a5bcd2b 障害が発生しているモジュール名: xxxx.dll_unloaded、バージョン: 0.0.0.0、タイム スタンプ: 0x4d92e27c 例外コード: 0xc0000005 xxxx.dllは、今回使用したいDLLです。 過去の質問等でスタックオーバーフローが発生した場合の解決策を探してはみたのですが、見つけられた方法が以下の2つでどちらもうまくいきませんでした。 (1)スタック領域を大きくする →スレッドでスタック領域を指定して実行してみました。 (2)ライブラリの中身をスタックオーバーフローが起きないように変更する → ライブラリの中身は変更できない状態です。 (1)のほうは、指定方法間違えてるかもしれません。。。 Thread newthread = new Thread(new ThreadStart(init), 0); もしくは、w3wp.exeでエラーが発生しているということはIIS関係で何かおかしなことをしてしまってるのかもとか・・・。 根本から見方が間違ってるかもしれませんが、(1)の方法の正しいやり方、もしくはそれ以外の解決策をご教授頂きますようよろしくお願いいたします。

  • スレッドを効率的に使うとは?

    C言語&C++で、pthreadを利用して、ファイルのコンバートをいかに早くできるかに挑戦します。 たとえば、CPUが2つある場合。 スレッドが1つだと、CPUの50%の性能しか出ない。だから、二つ目のスレッドを使うという風に理解しています。スレッドを二つ使うことで、100%CPUの力を引き出せる。 しかし、スレッドはCPUの数以上に、生成できるという風にも理解しています。もちろん上限はある。 ただし、その場合は2つのCPUをある時間単位でくぎって、スレッドにふりわけて使い回しをする。 ということは、フルにCPUを最速で使いたい場合は、CPUの数だけスレッドを生成して利用するという理解でいいでしょうか? また、大きなファイルの場合、ファイルにメモリに読み込んで二つにわけて、2つのスレッドを同時に走らせてはやく終わらせるということも可能なのでしょうか?おそらく、RAWのデータならできるけど、何かフォーマットがあるものは難しそうですね。

  • HDDクローン化について

    新しく購入したHDDを設置して、HDD1に300G(古)、HDD2に1T(新)の構成になっています。 「Acronis True Image」を使用して、OSごとクローン化したいと思います。少しマニュアル見ながら試したのですが、パーティションを変更してクローン化するのに質問です。 ・1Tのパーティションを切ったことがないのですが、一般的にシステム側をいくら見積もるべきでしょうか?自動で設定すると80Gに見積もられます。50Gでもいいきはするのですが、80Gと大きくしすぎても大丈夫でしょうか。基本的にOS、ドライバしかいれるきはありません。 ・HDD1はC20,D280、HDD2はL50,M950とクローン化されたと仮定します。 HDD2のOSを起動してHDD2をメインHDDとして使用する場合どうすればいいのでしょうか?HDD1は主に保険用として普段使用しないようにしたいのです。 初めてHDD交換を行いますので、他アドバイス等あれば教えてください。

  • スレッドとメッセージキューに関して

    現在、下記のようなプログラムを作成しています。 内容は、メッセージキューを受信するスレッドを生成するというイメージです。 処理内容は下記のようになります。  (1)メッセージキューの生成  (2)スレッド生成(メッセージキュー受信側)  (3)スレッド停止  (4)メッセージキューの削除 しかし、(3)のスレッド停止を実施しても、(4)のメッセージキューの削除以降にて、msgrcvのエラーが出力されてしまいます。 スレッド停止を行ったことから、TestThreadは動作しなくなり、(4)のメッセージキューの削除にて、エラーともならずに終了することを望んでりますが、上手くいきません。 下記に作成しているプログラムを記載いたします。 正常終了をするには何がいけないのでしょうか? ご教授宜しくお願い致します。 [test.cc] ---------------------------------------------------------------- #include <time.h> #include <stdio.h> #include <string.h> #include <errno.h> #include <fcntl.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <ctype.h> #include <stdlib.h> #include <pthread.h> #include <stdlib.h> #include <sys/ipc.h> #include <sys/msg.h> // メソッドポインタ定義 typedef void (*testT); // スレッドID pthread_t threadId; // メッセージキュー識別子 int msqId; // 送受信するメッセージ struct msgbuf{ long int type; char data[BUFSIZ]; }; // テストスレッド void TestThread() { // メッセージ struct msgbuf message; while( 1 ) { printf("### TEST ###\n"); printf("msq start\n"); // 受信 if( msgrcv( msqId, &message, BUFSIZ, 0, 0 ) == -1) { printf("ERR! msgrcv errno[%d]\n", errno); continue; } printf("msq ed\n"); sleep(1); } return; } // メイン int main(int argc, char *argv[]) { // メッセージキュー識別子退避変数 int testMsqid; // スレッド操作リターン値 int status; // スレッドa用のパラメータ pthread_t thread_test; printf("### TEST START ###\n"); // メッセージキューの作成 if( (testMsqid = msgget((key_t)1111, 0666 | IPC_CREAT)) == -1 ) { printf("ERR! CREATE bkMsqId[%d]\n", testMsqid); return 1; } // メッセージキュー識別子を共通変数に設定 msqId = testMsqid; printf("msgget OK\n"); sleep(5); // スレッドを生成 status = pthread_create(&thread_test, NULL, (void*(*)(void*))TestThread, (void*)NULL); if(status!=0) { printf("pthread_create ng\n"); return 1; } printf("pthread_create OK\n"); sleep(5); // スレッド停止 status = pthread_cancel(thread_test); // スレッド停止結果 if ( status != 0 ) { printf("pthread_cancel ng\n"); return 1; } printf("pthread_cancel OK\n"); sleep(5); // メッセージキューの削除 if ( msgctl( msqId, IPC_RMID, NULL) == -1 ) { printf("msqId[%d] errno[%d]\n", msqId, errno); return 1; } printf("msgctl OK\n"); sleep(5); printf("### TEST E N D ###\n"); return 0; } ----------------------------------------------------------------

  • クローンHDDスタンド

    OEM版コピー の場合、ライセンスの事がきになります クローンを作って、換装した場合どうなるか? よくわかりませんが コピー先のパソコンだけなら(認証できる)?(認証は必要ない)?  他のPCで使用しません。     購入するか、、、迷っています アドバイスよろしくおねがいします。  

専門家に質問してみよう