... или я должен написать свой собственный? (Кстати, я работаю на C)
Я пишу реализацию, похожую на то, что есть в википедии:
volatile int lock = 0;
void Critical() {
while (TestAndSet(&lock) == 1);
critical section // only one process can be in this section at a time
lock = 0 // release lock when finished with the critical section
}
Но я не могу найти готовый TestAndSet(volatile int *lock)
.
Примеры того, как они могут выглядеть, включают:
#define LOCKED 1
int TestAndSet(volatile int* lockPtr) {
int oldValue;
oldValue = *lockPtr;
*lockPtr = LOCKED;
return oldValue;
}
В идеале я хотел бы что-то, что может работать как на Linux, так и на Windows. Кроме того, я читал, что выполнение атомарных инструкций зависит от аппаратного обеспечения. Я не уверен, что это играет роль или как определить, поддерживает ли это оборудование, а затем запустить альтернативу.
Благодарю вас!
Дополнительная контекстная информация. Причина, по которой я задаю этот вопрос, заключается в разработке набора функций для доступа к структуре данных (например, add() fetch() delete() и т. д.). Несколько потоки обращаются к нему для модификации и отображения определенных элементов в реальном времени.
Мьютексы: я голосовал против мьютексов (поправьте меня, если мое обоснование необоснованно), потому что критической областью является не вся хэш-таблица, а конкретный элемент, к которому обращается данная функция. Таким образом, использование мьютекса приведет к снижению производительности всей структуры данных.
Альтернатива: я обратил внимание на TestAndSet() потому, что имело больше смысла помещать флаг «BeingAccessed» для каждого элемента в структуре данных. Этот флаг проверяется функцией, которая хочет получить к нему доступ, устанавливается в значение true, если оно ложно, а затем функция делает то, что должна, а затем освобождает этот элемент, не замораживая всю структуру.
Комментарий @M.M: Пример реализации показался неправильным по причине, которую @chux и вы оба упомянули. Насколько я понимаю, занятое ожидание используется на низком уровне для разработки механизмов синхронизации более высокого уровня. Пожалуйста, смотрите мое редактирование выше: мьютексы. Волатильность не была попыткой обеспечить атомарность, но чтобы гарантировать, что значение загружается каждый раз, когда к нему обращаются, когда оно проверяется атомарной функцией, потому что несколько потоков могут изменить эту переменную в любое время. Атомарность, которую я представляю/надеюсь, обеспечивается функцией, действующей на рассматриваемую переменную. Вопрос, относящийся к тому, что вы написали: ваш код говорит: «Примечание: не используйте «изменчивый»», но предоставленный вами стандартный прототип функции является изменчивым, поэтому переменная флага энергонезависимости приведена как изменчивая в атомарной функции? Спасибо.
volatile
. 04.03.2016