Если инвариант между двумя данными должен храниться во всех потоках, заставляет ли он читать / записывать эти данные в критическую секцию?

Я пытался установить инвариант между двумя атомными счетчиками в одном потоке, гарантируя, что этот инвариант был сохранен во время чтения в другом потоке без использования мьютекса.

Тем не менее, глядя на код, кажется, что я только что реализовал какой-то алгоритм блокировки, используя два атомных счетчика (с риском, который я только что испортил).

Можно ли разделить инвариант между потоками без использования стратегии блокировки?


РЕДАКТИРОВАТЬ: термин инвариант не может быть адекватным.

Допустим, у меня есть две переменные а также б, в какой-то момент выполнения программы поток A множество а также б к некоторым различным значениям, и после этого я хотел бы, чтобы поток B загружал значение хранится в A, а затем загрузить б, загруженное значение б тот, который хранится в A, а не значение, сохраненное позже в б.

3

Решение

Можно ли разделить инвариант между потоками без использования стратегии блокировки?

Нет.

Зачем? Представьте себе следующий сценарий: нить X и Y, счетчики a а также b,

Поток X пишет в a а также b, что приводит к разрыву инварианта. Предполагая, что поток Y пытается прочитать a а также b, в то время как инвариант нарушен и без какой-либо стратегии блокировки.

В этом случае поток Y может читать устаревшие (или слишком свежие) данные, так как a может быть значением, которое X написал сейчас, или предыдущим. То же самое означает b,

Это классическая ошибка в многопоточности, которая приводит к гонки данных.


Это похоже на пример двойного связанного списка Вот. В этом случае потоки X и Y существуют и управляют двойным связанным списком. Один из инвариантов заключается в том, что если мы следуем по следующему указателю от одного узла (1) к другому (2), предыдущий указатель с этого узла (2) указывает на первый узел (1).

Предполагая, что поток X удаляет узел списка, поток Y пытается прочитать в этой точке и может вызвать проблемы, поскольку существует вероятность того, что указатели предыдущего и следующего узлов узла, которые будут удалены X, еще не установлены (таким образом, инвариант прерывается в то время, когда поток Y пытается прочитать список).

4

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]