Первое, что мне сказали, когда я начал работать с pthreads, было - вы должны избегать принудительной отмены потока, например, pthread_cancel. Вместо этого мы должны использовать уведомление об отмене потока через канал связи потоков.
Если у нас есть очень длинная задача для выполнения в потоке, мы разбиваем эту задачу на небольшие фрагменты и проверяем флаг отмены после обработки каждого фрагмента. Как это:
loop {
process_chunk();
if (check_cancel_flag())
break;
}
Но как лучше реализовать эту функцию check_cancel_flag()?
При всем моем опыте в c и linux я могу вспомнить только эти методы:
(Если у вас есть только один рабочий поток) Вы можете использовать sig_atomic_t в качестве типа для флага отмены. Проверьте его в функции check_cancel_flag() и отметьте его как true в обработчике сигнала потока. Затем просто вызовите pthread_kill из основного потока.
Используйте любой тип POD для флага отмены и защитите его мьютексом. В этом случае вы слишком часто будете получать накладные расходы на блокировку вызова.
Использовать мьютекс в качестве флага отмены. Проверьте это вызовом pthread_mutex_trylock. Если основной поток освобождает этот мьютекс, пора завершить работу рабочего потока.
(Для C11) Используйте встроенные функции gcc _atomic (или другую библиотеку asm atomic) для установки и проверки флага отмены.
Я больше ничего не мог вспомнить.
Вопрос: Как выбрать правильный подход? Знаете ли вы какие-либо ориентиры по этой проблеме?
_Atomic
для типов данных, которая помогает.sig_atomic_t
никогда не подходит, его единственные гарантии относятся к обработчикам сигналов, и там он гарантирует только неделимость, а не другие свойства согласованности памяти, которые вы хотели бы иметь. - person Jens Gustedt   schedule 28.06.2017