JPCERT コーディネーションセンター

CON04-C. 終了ステータスが重要でないスレッドでも、join または detach する

thrd_detach() 関数は、スレッドに割り当てられているリソースが終了時に回収可能であることをシステムに知らせるために使われる。この関数は、他のスレッドが終了状態を必要としないときに使用するべきである。

スレッドを detach せずに終了すると、スレッドのスタックが解放され、thrd_join() または thrd_detach() によってスレッドが破棄されるまで、ヒープや OS レベルのオブジェクトも含めすべてのリソースが残ったままになる。これらのリソースは、リソースが限られているシステムにとっては不可欠である場合があり、どの重要リソースが先に使い果たされるかにもよるが、エラーを引き起こす可能性がある。起こりやすいエラーの 1 つに、EAGAIN (Resource unavailable, try again)がある。これは、他のプロセス、スレッド、またはミューテックスの作成や初期化を行うリソースが不足したときに、fork()thrd_create()mtx_init() などの関数によって設定される。

違反コード

次のコード例は、正しく終了されていないスレッドプールを示している。

size_t const thread_no = 5;
char mess[] = "This is a test";

void *message_print(void *ptr){
  char *msg;
  msg = (char *) ptr;
  printf("THREAD: This is the Message %s\n", msg);
}

int main(void){
  int error = 0;
  size_t i = 0;
  /* スレッドプールを作成 */
  thrd_t thr[thread_no];
  for (i = 0; i < thread_no; i++) {
    error = thrd_create( &(thr[i]), message_print, (void *) mess);
    /* エラー処理 */
  }
  printf("MAIN: Thread Message: %s\n", mess);
  thrd_exit(NULL);
}
適合コード

次の適合コードでは、終了時にリソースを回収できるように、message_print() 関数の代わりにスレッドを適切に detach できる同様の関数を使用している。

size_t const thread_no = 5;
char mess[] = "This is a test";

void *message_print(void *ptr){
  int error = 0;
  char *msg;

  /* スレッドをデタッチ */
  error = thrd_detach(thrd_current());
  /* もしあればエラー処理 */

  msg = (char *) ptr;
  printf("THREAD: This is the Message %s\n", msg);
}

int main(void) {
  int error = 0;
  size_t i = 0;
  /* スレッドプールを作成 */
  thrd_t thr[thread_no];
  for(i = 0; i < thread_no; i++) {
    error = thrd_create( &(thr[i]), message_print, (void *) mess);
    /* エラー処理 */
  }
  printf("MAIN: Thread Message: %s\n", mess);
  thrd_exit(NULL);
}
リスク評価

レコメンデーション

深刻度

可能性

修正コスト

優先度

レベル

CON04-C

P1

L3

参考資料
[Open Group 2004] pthread_detach
翻訳元

これは以下のページを翻訳したものです。

CON04-C. Join or detach threads even if their exit status is unimportant (revision 40)

Top へ

Topへ
最新情報(RSSメーリングリストTwitter