Следующий список указывает некоторые из наиболее частых оплошностей
и ошибок, которые могут вызвать ошибки в многопоточных программах.
Передача указателя на стек вызывающего потока как аргумента в новый
поток.
Доступ к глобальной памяти без использования механизмов синхронизации.
Создание тупиков, вызванных двумя потоками, пробующими получить права
на одну и ту же пару глобальных ресурсов в различном порядке (один
поток управляет первым ресурсом, а второй управляет другим ресурсом
и ни один может продолжать выполнение до освобождения нужного ресурса).
Попытка повторно получить доступ к уже захваченному ресурсу (рекурсивный
тупик).
Создание скрытого промежутка при синхронизации. Это происходит, когда
сегмент кода, защищенный механизмом синхронизации содержит вызов функции,
которая освобождает и затем повторно создает механизм синхронизации
прежде, чем управление возвращается к вызывающему потоку. В результате
вызывающему кажется, что глобальные данные были защищены, хотя это
не так.
Смешивание сигналов UNIX с потоками - лучше использовать sigwait()
для того, чтобы обрабатывать асинхронные сигналы.
Невнимание к тому факту, что потоки по умолчанию создаются с типом
PTHREAD_CREATE_JOINABLE и должны быть утилизированы через
pthread_join(). Обратите внимание, что pthread_exit()
не освобождает выделенную память.
Создание глубоко вложенных, рекурсивных обращений и использование
больших автоматических массивов может вызвать проблемы, потому что
многопоточные программы имеют более ограниченный размер стека, чем
однопоточные.
Определение неадекватного размера стека или использование стека не
по умолчанию.