メインコンテンツ

このページの内容は最新ではありません。最新版の英語を参照するには、ここをクリックします。

マルチスレッド プログラムの信号呼び出し

複数のスレッドを使用するプログラムでの関数 signal の使用

説明

このチェッカーは、既定の Polyspace® as You Code 解析では非アクティブにされますPolyspace as You Code 解析で非アクティブにされるチェッカー (Polyspace Access)を参照してください

この欠陥は、複数のスレッドを使用するプログラムで関数 signal() を使用した場合に発生します。

リスク

C11 規格 (節 7.14.1.1) によると、マルチスレッド プログラムでの関数 signal() の使用は未定義の動作です。

修正方法

目的に応じて、他の方法を使用して特定のスレッドに対して非同期アクションを実行します。

すべて展開する


#include <signal.h>
#include <stddef.h>
#include <threads.h>

volatile sig_atomic_t flag = 0;

void handler(int signum) {
  flag = 1;
}

/* Runs until user sends SIGUSR1 */
int func(void *data) {
  while (!flag) {
    /* ... */
  }
  return 0;
}

int main(void) {
  signal(SIGINT, handler); /* Undefined behavior */
  thrd_t tid;

  if (thrd_success != thrd_create(&tid, func, NULL)) {
    /* Handle error */
  }
  /* ... */
  return 0;
}

この例では、thrd_create を使用して作成したスレッドで関数 signal を使用することで while ループを終了しています。

修正 — atomic_bool 型の変数を使用してループを終了

1 つの修正方法として、複数のスレッドからアクセスできる atomic_bool 型の変数を使用します。この修正例では、すべてのループ反復の前に子スレッドでこの変数が評価されます。プログラムの完了後、子スレッドがループから抜け出せるようにこの変数を変更できます。


#include <stdatomic.h>
#include <stdbool.h>
#include <stddef.h>
#include <threads.h>
  
atomic_bool flag = ATOMIC_VAR_INIT(false);
 
int func(void *data) {
  while (!flag) {
    /* ... */
  }
  return 0;
}
 
int main(void) {
  thrd_t tid;
   
  if (thrd_success != thrd_create(&tid, func, NULL)) {
    /* Handle error */
  }
  /* ... */
  /* Set flag when done */
  flag = true;
 
  return 0;
}

結果情報

グループ: 同時実行
言語: C | C++
既定値: オフ
コマンド ライン構文: SIGNAL_USE_IN_MULTITHREADED_PROGRAM
影響度: Low

バージョン履歴

R2018b で導入