exponenta event banner

Отсутствует или выполняется двойная инициализация атрибута потока

Дублированная инициализация атрибутов потока или неинициализированных атрибутов потока, используемых в функциях, которые ожидают инициализированных атрибутов

Описание

Этот дефект возникает во время одной из следующих ситуаций:

  • Инициализация атрибута потока выполняется дважды с помощью такой функции, как pthread_attr_init без промежуточного вызова функции, такой как pthread_attr_destroy.

    Функция pthread_attr_destroy уничтожает объект атрибута потока и позволяет системе восстановить ресурсы, связанные с объектом.

  • Неинициализированный атрибут потока используется в функции, например pthread_create, который ожидает инициализированный атрибут. Атрибут потока может быть неинициализирован, так как он никогда не был инициализирован ранее или уничтожен с помощью pthread_attr_destroy функция.

    Неинициализированные атрибуты потока обнаруживаются для всех функций в стандарте POSIX ®.

На панели Сведения о результате (Result Details) описывается, является ли атрибут двойным инициализированным или неинициализированным, а также отображаются предыдущие связанные события.

Обратите внимание, что атрибут потока считается инициализированным, только если вызов pthread_attr_init успешно. Например, атрибут потока не инициализирован в if ветвь здесь:

pthread_attr_t attr;
int thread_success;

thread_success = pthread_attr_init(&attr);
if(thread_success != 0) {
   /* Thread attribute considered noninitialized */
}
Проблема также помечается, если не проверить возвращаемое значение из вызова pthread_attr_init.

Риск

Инициализация атрибута потока без уничтожения ранее инициализированного атрибута или использования неинициализированных атрибутов потока приводит к неопределенному поведению.

Зафиксировать

Перед использованием атрибута потока инициализируйте атрибут с помощью pthread_attr_init функция.

pthread_attr_t attr;
int thread_success;

/* Initialize attribute */
thread_success = pthread_attr_init(&attr);
if(thread_success != 0) {
   /* Handle initialization error */
}
...
/* Use attribute */
thread_sucess = pthread_create(&thr, &attr, &thread_start, NULL);
После инициализации удалите атрибут потока с помощью pthread_attr_destroy перед повторной инициализацией:
pthread_attr_t attr;
int thread_success;

/* Destroy attribute */
thread_success = pthread_attr_destroy(&attr);
if(thread_success != 0) {
   /* Handle destruction error */
}
...
/* Reinitialize attribute */
thread_success = pthread_attr_init(&attr);

Примеры

развернуть все

#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_create(&id, &attr, thread_func, NULL)) {
    }

    return 0;    
}

В этом примере атрибут attr не инициализирован до его использования в pthread_create звоните.

Исправление - инициализация атрибута потока перед использованием

Перед использованием атрибута потока в pthread_create , инициализировать атрибут с помощью pthread_attr_init функция.

#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_create(&id, &attr, thread_func, NULL)) {
    }
    
    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;
    
    pthread_attr_init(&attr);
   
    if(thread_success == pthread_create(&id, &attr, thread_func, NULL)) {
    }
    
    return 0;    
}

В этом примере возвращаемое значение pthread_attr_init не проверяется. Если инициализация атрибута потока завершается неуспешно, ошибка не обрабатывается. Возможно, неопределенный атрибут потока позже используется в pthread_create функция.

Исправление - обработка ошибок при инициализации атрибута потока

Одной из возможных корректировок является использование атрибута потока только в том случае, если возвращаемое значение из pthread_attr_init указывает на успешную инициализацию.

#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_create(&id, &attr, thread_func, NULL)) {
    }
    
    return 0;    
}

Информация о результатах

Группа: Параллелизм
Язык: C
По умолчанию: Откл.
Синтаксис командной строки: BAD_THREAD_ATTRIBUTE
Воздействие: среднее
Представлен в R2019b