Переменная передается от одного потока до другого, не гарантируя, что переменная остается в живых через длительность последнего потока
Этот дефект происходит, когда автоматическая локальная переменная или локальная переменная потока передаются адресом от одного потока до другого потока, не гарантируя, что переменная остается в живых через длительность последнего потока.
Дефектное средство проверки применяется и к C11 и к потокам POSIX®.
Автоматическая локальная переменная или локальная переменная потока выделяются на стеке в начале потока, и его время жизни расширяет до конца потока. Переменная, как гарантируют, не будет жива, когда различный поток получит доступ к ней.
Например, рассмотрите функцию запуска потока C11 с этими линиями:
int start_thread(thrd_t *tid) { int aVar = 0; if(thrd_success != thrd_create(tid, start_thread_child, &aVar) { ... } }
thrd_create
функция создает дочерний поток с функцией запуска start_thread_child
и передает адрес автоматической переменной aVar
к этой функции. Когда этот дочерний поток доступы aVar
, родительский поток может завершить выполнение и aVar
больше не находится на стеке. Доступ может привести к чтению непредсказуемых значений.
Когда вы передаете переменную от одного потока до другого, убедитесь, что переменное время жизни совпадает или превышает время жизни обоих потоков. Можно достигнуть этой синхронизации одним из этих способов:
Объявите переменную static
так, чтобы это не выходило из стека, когда текущий поток завершает выполнение.
Динамически выделите устройство хранения данных для переменной так, чтобы это было выделено на куче вместо стека и должно было быть явным образом освобождено. Убедитесь, что освобождение происходит после обоих потоков полное выполнение.
Эти решения требуют, чтобы вы создали переменную в нелокальной памяти. Вместо этого можно использовать другие решения, такие как shared
ключевое слово с интерфейсом поточной обработки OpenMP, который позволяет вам безопасно совместно использовать локальные переменные через потоки.
Группа: параллелизм |
Язык: C | C++ |
Значение по умолчанию: 'off' |
Синтаксис командной строки:
LOCAL_ADDR_ESCAPE_THREAD |
Удар: носитель |