メインコンテンツ

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

CERT C: Rule CON39-C

以前に結合または分離されたスレッドを結合したり分離したりしない

説明

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

ルール定義

ロックの保持中にブロックを行う可能性がある操作を実行しないようにします。1

Polyspace 実装

ルール チェッカーは、"結合済みまたは分離済みスレッドの結合または分離" をチェックします。

すべて展開する

問題

結合済みまたは分離済みスレッドの結合または分離は、次の場合に発生します。

  • 結合されるスレッドが以前に結合または分離されたスレッドである。

  • 分離されるスレッドが以前に結合または分離されたスレッドである。

[結果の詳細] ペインには、そのスレッドが以前に結合または分離されたかどうかが表示されます。また、それまでの関連するイベントも表示されます。

たとえば、この問題は次のように、thrd_join で結合されたスレッドが pthread_detach で分離される場合に発生します。

thrd_t id;
//...
thrd_join(id, NULL);
thrd_detach(id);

スレッドが結合済みと見なされるのは、以前のスレッド結合が成功した場合のみです。たとえば、次の if 分岐ではスレッドは結合済みと見なされません。

thrd_t t;
//...
if (thrd_success != thrd_join(t, 0)) {
    /* Thread not considered joined */
}
関数 thrd_current() などを使用して結合済みスレッドを分離させる場合、解析では検出できません。

リスク

C11 規格 (7.26.5.3 節および 7.26.5.6 節) では、結合または分離したことのあるスレッドを結合または分離してはならないと規定しています。規格のこれらの節に違反することは未定義の動作になります。

修正方法

以前に結合または分離されたスレッドは結合しないようにします。同様に、既に結合または分離されたスレッドは分離しないようにします。

例 – スレッド結合後のスレッド分離

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


extern int thread_func(void *arg);

int main (void)
{
  thrd_t t;

  if (thrd_success != thrd_create (&t, thread_func, NULL)) {
    /* Handle error */
    return 0;
  }

  if (thrd_success != thrd_join (t, 0)) {   
    /* Handle error */
    return 0;
  }

  if (thrd_success != thrd_detach (t)) {    //Noncompliant
    /* Handle error */
    return 0;
  }

  return 0;
}

この例では、以前に thrd_join で結合されたスレッドに対して thrd_detach を使用しているため、未定義の動作を発生させてしまいます。

この例でコンパイル エラーを回避するには、オプション [C 標準バージョン] (-c-version) を使用して C11 規格を指定します。

修正 – 結合済みスレッドの分離を回避

thrd_join ステートメントまたは thrd_detach ステートメントを削除します。


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


extern int thread_func(void *arg);

int main (void)
{
  thrd_t t;

  if (thrd_success != thrd_create (&t, thread_func, NULL)) {
    /* Handle error */
    return 0;
  }

  if (thrd_success != thrd_join (t, 0)) {   
    /* Handle error */
    return 0;
  }

  return 0;
}
例 – 分離状態で作成されたスレッドの結合
#include <stddef.h>
#include <pthread.h>
#define thread_success 0

extern void *thread_func(void *arg);


int main() {
    pthread_t id;
    pthread_attr_t attr;
    
    if(thread_success != pthread_attr_init(&attr)) {
        return 0;
    }
   
    if(thread_success != pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED)) {
        return 0;
    }
       
    if(thread_success != pthread_create(&id, &attr, thread_func, NULL)) {
            return 0;
    }
    
    if(thread_success != pthread_join(id, NULL)) { //Noncompliant
            return 0;
    }

    return 0;    
}

この例では、スレッド属性に状態 PTHREAD_CREATE_DETACHED が割り当てられます。この属性を使用して作成されたスレッドが結合されます。

修正 – 結合可能なスレッドとして作成

1 つの修正方法として、スレッド属性に状態 PTHREAD_CREATE_JOINABLE が割り当てられたスレッドを作成してから、そのスレッドを結合します。

#include <stddef.h>
#include <pthread.h>
#define thread_success 0

extern void *thread_func(void *arg);


int main() {
    pthread_t id;
    pthread_attr_t attr;
    
    if(thread_success != pthread_attr_init(&attr)) {
        return 0;
    }
   
    if(thread_success != pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE)) {
        return 0;
    }
       
    if(thread_success != pthread_create(&id, &attr, thread_func, NULL)) {
            return 0;
    }
    
    if(thread_success != pthread_join(id, NULL)) {
            return 0;
    }

    return 0;    
}

チェック情報

グループ: Rule 14.同時実行 (CON)

バージョン履歴

R2019b で導入


1 This software has been created by MathWorks incorporating portions of: the “SEI CERT-C Website,” © 2017 Carnegie Mellon University, the SEI CERT-C++ Web site © 2017 Carnegie Mellon University, ”SEI CERT C Coding Standard – Rules for Developing safe, Reliable and Secure systems – 2016 Edition,” © 2016 Carnegie Mellon University, and “SEI CERT C++ Coding Standard – Rules for Developing safe, Reliable and Secure systems in C++ – 2016 Edition” © 2016 Carnegie Mellon University, with special permission from its Software Engineering Institute.

ANY MATERIAL OF CARNEGIE MELLON UNIVERSITY AND/OR ITS SOFTWARE ENGINEERING INSTITUTE CONTAINED HEREIN IS FURNISHED ON AN "AS-IS" BASIS. CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY KIND, EITHER EXPRESSED OR IMPLIED, AS TO ANY MATTER INCLUDING, BUT NOT LIMITED TO, WARRANTY OF FITNESS FOR PURPOSE OR MERCHANTABILITY, EXCLUSIVITY, OR RESULTS OBTAINED FROM USE OF THE MATERIAL. CARNEGIE MELLON UNIVERSITY DOES NOT MAKE ANY WARRANTY OF ANY KIND WITH RESPECT TO FREEDOM FROM PATENT, TRADEMARK, OR COPYRIGHT INFRINGEMENT.

This software and associated documentation has not been reviewed nor is it endorsed by Carnegie Mellon University or its Software Engineering Institute.