Здравствуйте, Maxim S. Shatskih, Вы писали:
S_N>>Для изменения всего лишь одного бита вводить ВСЕГДА критические секции совсем неэффективно. Ведь реально — РЕДКИЙ СЛУЧАЙ, когда оба потока будут ломиться именно к одному значению int в массиве. Поэтому, зачем лишние блокировки? Я решил синхронизировать потоки так — сначала поток записывает в специальную переменную тот номер int из массива который он намерен "захватить", и только потом его меняет. 2-й поток будет приостановлен только в РЕДКИХ случаях когда оба потока одновременно захотят изменить это значение. Т.е. 2-й поток увидев что значение захвачено и используется, сбросит свою метку,(он же тоже уже пометил, что хочет захватывать это значение), и заснет на какое-то время. Потом снова пометит, что он хочет менять, снова проверит, не захвачено ли значение другим потоком и т.д
MSS>Т.е. спинлок, хранящий в себе указатель на данные. Что ж... первый шаг к lock-free data structures выглядит именно так, только писать надо очень аккуратно и вдумчиво.
Я вот тщательно все обдумал и пришел к выводу, что мой подход, несмотря на то, что операции записи-чтения меток (которые показывают то, что именно потоки "захватывают") и атомарны, все равно может дать ошибку, но ТОЛЬКО на многопроцессорных машинах. Это теоретически может произойти если планировщик потоков назначит эти два потока на разные CPU. Тогда 1-й поток сделает пометку чтобы 2-й поток приостановился, если ему нужен определенный элемент... Но процессор сразу не отправит в ОП а запишет в кэш процессора. 2-й поток на другом процессоре, будет читать или из своего кэша или из ОП, и в обоих случаях он не увидит ЧТО МЕТКА ИЗМЕНИЛАСЬ, ХОТЯ 1-й ПОТОК ДЕЙСТВИТЕЛЬНО ЕЕ УЖЕ ИЗМЕНИЛ!
Как можно на C++ ЗАСТАВИТЬ процессор отправить переменную, которая только что изменилась, НЕМЕДЛЕННО (!) в оперативную память? Чтобы она не попадала предварительно в кэш. И второе — как заставить (для второго процессора) прочитав переменную, не хранить ее в кэше, т.е. при каждой попытке чтения — чтобы она читалась именно из оперативной памяти? На C# такое, я читал, можно сделать. А можно ли на C++ ?