У меня есть функция, которая проходит через массив указателей функций и вызывает каждую из этих функций по порядку.Вызов функции указателем, находящимся в массиве при изменении содержимого массива
Что произойдет, если содержимое массива указателей функций будет изменено во время этого процесса? Можно ли считать вызовы функций достаточно атомными, чтобы быть уверенными в том, что ничего неожиданного не происходит или нужно не менять указатели на функции, например, когда происходит нажатие на стек?
Следующий пример (псевдошум). init() запускается один раз при запуске, а функция callFunctions() запускается периодически, скажем, раз в секунду. Затем изменяется changeFunctions() и изменяет содержимое функцииPtrArray []. Это может произойти в любой момент времени, поскольку код запускается в разных процессах как ОС, подобный среде.
void (*functionPtrArray[3]) (void);
void init(void)
{
functionPtrArray[0] = function1;
functionPtrArray[1] = function2;
functionPtrArray[2] = function3;
}
void callFunctions(void)
{
for (i = 0; i < 3; i++)
{
*functionPtrArray[i]();
}
}
void changeFunctions(void)
{
functionPtrArray[0] = newFunction1;
functionPtrArray[1] = newFunction2;
functionPtrArray[2] = newFunction3;
}
Ключевой вопрос заключается в том, важно ли, чтобы после выполнения f [0] f [1] и f [2] были выполнены с тем же набором, что и f [0]. В противном случае ваш код в порядке (при условии, что извлечение и сохранение указателя функции являются атомарными, в основном это означает, что они являются родным размером процессора и размера шины, поэтому циклы чтения/записи извлекают/сохраняют целые собственные машинные слова за один цикл). –
@PaulOgilvie Что заставляет вас думать, что какой-либо данный общий процессор может читать слово (x байтов) за один цикл? Даже если это предположение было истинным, а это не так, многие архитектуры имеют расширенные адреса за пределами размера машинного слова, предназначенные для хранения как кода, так и данных. – Lundin