Я использую API обратного вызова PortAudio для разработки библиотеки обратной связи обработки сигналов.
Я хотел бы добавить ветку, которая зависит от флага внутри обратного вызова, например
int pa_callback(const void *inputuffer,
void *outputBuffer,
unsigned long frameCount,
const PaStreamCallbackTimeInfo *timeInfo,
PaStreamCallbackFlags statusFlags,
void *userData)
{
if (do_something_flag) {
do_something(inputBuffer, outputBuffer, frameCount);
} else {
do_something_else(inputBuffer, outputBuffer, frameCount);
}
return paContinue;
}
Где do_something_flag
устанавливается в другом месте моей программы через равные промежутки времени.
В документации обратного вызова PortAudio указано:
Прежде чем мы начнем, важно понять, что обратный вызов — это деликатное место. Это связано с тем, что некоторые системы выполняют обратный вызов в специальном потоке или обработчике прерывания, и он редко обрабатывается так же, как остальная часть вашего кода. Для большинства современных систем вы не сможете вызвать сбои, выполнив запрещенные вызовы в обратном вызове, но если вы хотите, чтобы ваш код воспроизводил звук без сбоев, вам нужно убедиться, что вы избегаете вызовов функций, которые могут занимать неограниченное время. количество времени на выполнение. Что именно это зависит от вашей платформы, но почти наверняка включает следующее: выделение/освобождение памяти, ввод-вывод (включая файловый ввод-вывод, а также консольный ввод-вывод, например printf()), переключение контекста (например, exec () или yield()), операции с мьютексами или что-то еще, что может зависеть от ОС. Если вы считаете, что короткие критические разделы безопасны, прочтите об инверсии приоритетов.
Меня не волнует атомарность do_something_flag
. То есть мне все равно, сколько циклов потребуется, чтобы получить правильное значение (в пределах разумного). Согласно документации, похоже, я не могу использовать мьютексы для установки/чтения этой переменной.
1) Какие у меня есть варианты?
2) Если я сделаю его глобальным и установлю его в другой части моей программы (в другом потоке), что произойдет в худшем случае? Опять же, я имею в виду повреждение данных вплоть до сбоя программы и т. д.
Есть ли правильный способ сделать это?