Здравствуйте, netch80, Вы писали:
N>Фух... надеюсь, теперь понятно.
Техническая сторона вопроса и раньше была понятна, я не отрицаю существования такой проблемы, но считаю, что метод ее решения — использование volatile — в общем случае неприемлим, и применять его "на всякий случай" неправильно.
Оптимизация, производимая компилятором — вторична, программиста не должно заботить, где находятся промежуточные результаты вычислений: в памяти ли или в регистрах. Нити одного процесса по определению выполняются в одном адресном пространстве, поэтому если первая нить выполняет:
...
foo = 1;
unlock();
а вторая:
lock();
use(foo);
...
и lock()/unlock()
предназначены для синхронизации, то
1) use(foo)
не должен выполниться ранее, чем отработает unlock()
2) foo
должна содержать корректное значение, присвоенное перед unlock().
Иначе теряется смысл как нитевой модели, так и присвоения значений переменным вцелом.
И как работать в мультинитевой среде с более сложными структурами данных? Представляешь, во что выльется объявление volatile A в чем-то типа:
lock();
for (i=2; i<ARRAY_SIZE(A); i++)
{
A[i] = (A[i-1]+A[i-2])/2;
}
signal();
unlock();
?
Или ради возможности оптимизации за счет кеширования результатов оптимизацию таких ситуаций возложить на программиста?