Сабж.
Делаю тут ALSA-воспроизводилку звука, вся загрузка данных из файла - в отдельном потоке. Используются два больших раздельных буфера, объёма достаточного для хранения примерно 8 секунд при 44100/16. Загрузка данных во второй - когда ещё только начал воспроизводиться первый. Даже если за 8 секунд параллельный поток не успел прочитать данные с диска (что невероятно), ничего не произойдёт и воспроизводиться будет мусор. Переключение между блоками - пара операций сравнения, перезапись пары переменных, т.е. ерунда.
ALSA просит данные по коллбеку. За раз в неё отправляется примерно 940 фреймов (фрейм = sizeof(short)*channels). То есть коллбеки происходят 46 раз в секунду.
В неопределённом месте - всегда по-разному - после минуты или после 10 минут звучания всё виснет нафиг, причём все потоки сразу. 10 минут - это тот срок, когда все механизмы уже успели отработать по многу раз - и загрузка данных и переключение между буферами и т.п. Т.е. всё классно и без щелчков звучит. Отладка показала, что в момент зависания происходит уникальное событие - когда только начал выполняться коллбек ALS-Ы, в него делается ещё один заход. То есть предыдущий handler не успел выполниться, начинается его выполнение ещё раз. Читал, что коллбеки ALSA инициируются сигналами. То есть библиотека ловит сигнал, вызывает переданную ей функцию, которая и есть мой хендлер.
1. Возможно ли такое вообще? 2. Если он вызвался второй раз, когда ещё идёт выполнение первого - значит в деле учавствуют 2 каких-то потока? 3. Какой поток/процесс вызывает обработчики сигналов для процесса в linux? Т.е. в контексте какого «control flow» идёт исполнение кода обработчика сигнала? Как такое возможно? В гугл не отсылайте пожалуйста, просто напишите как это возможно и всё (-; (-; (-; 4. И чё делать :) ? В хэндлере поубирал все std::cout, никаких выделений памяти, никаких тяжёлых операций - работа только с заранее выделенной памятью, переменными класса и т.п. - всё равно случается жОсткий зависон изредка.
void MyALSACallback()
{
std::cout << "1"; std::cout.flush();
// ... snd_pcm_writei() call ... //
// ... no any returns ... //
std::cout << "2"; std::cout.flush();
return;
}
Когда всё хорошо, в консоли валится «1212121212...», перед зависанием встречается уникальная последовательность «11».
Короче главный вопрос - вопрос из сабжа.
Спасибо.