Предположим, что у меня есть программа, которая инициализирует глобальную переменную для использования потоками, например:
int ThreadParameter;
// this function runs from the main thread
void SomeFunction() {
ThreadParameter = 5;
StartThread(); // some function to start a thread
// at this point, ThreadParameter is NEVER modified.
}
// this function is run in a background worker thread created by StartThread();
void WorkerThread() {
PrintValue(ThreadParameter); // we expect this to print "5"
}
Эти вопросы должны применяться для любой общей архитектуры процессора, с которой можно столкнуться. Я хочу, чтобы решение было портативным - не специфичным для архитектуры с более надежными гарантиями памяти, такими как x86.
- Общий вопрос: несмотря на то, что он очень распространен, действительно ли это безопасно для всех процессорных архитектур? Как сделать это безопасным, если нет?
- Глобальная переменная не
volatile
; возможно, он будет переупорядочен после вызоваStartThread()
и оставить меня в покое? Как исправить эту проблему? - Предположим, что на компьютере есть два процессора, у которых есть свои собственные кеши. Основной поток работает на первом процессоре, а рабочий поток работает на втором процессоре. Предположим, что блок памяти, содержащий
ThreadParameter
, был загружен в каждый кеш процессора до начала запуска программыSomeFunction()
.SomeFunction()
записывает5
вThreadParameter
, который сохраняется в первом кэше процессора, а затем запускает рабочий поток, который выполняется на втором процессоре. Не будет лиWorkerThread()
для второго процессора видеть неинициализированные данные дляThreadParameter
вместо ожидаемого значения5
, так как страница памяти второго процессора еще не увидела обновления от первого процессора? - Если требуется что-то другое - как лучше всего справиться с этим, а не простым
int
, я мог бы работать с указателем на гораздо более сложные типы данных, которые не обязательно используются в многопоточной среде?
Если мои опасения необоснованны, каковы конкретные причины, по которым мне не нужно беспокоиться?