Вот как вы делаете это в 50 раз быстрее, чем дедушка мьютекс (мы тестировали подобные вещи). Используйте gcc атомарные операции. Вы также можете использовать атомарные операции Linux, если они включены в ваш выпуск.
typedef union _foo {
struct {
unsigned int a:1,
b:6,
q:2;
} Data;
unsigned int n32;
} TFoo;
TFoo _GlobalFoo;
SomeFuncThatChangesFoo_A(int fNewA)
{
TFoo Old, New;
while(1) {
// get a copy of the current state
Old.n32 = _GlobalFoo.n32;
New.n32 = Old.n32;
New.Data.a = fNewA;
// compare and swap is the atomic operation.
// if _GlobalFoo hasn't changed since we copied it to "Old", then change _GlobalFoo to "New".
// __sync_bool_compare_and_swap works on basic types (8 bit, 16 bit, 32 bit, 64 bit, 128 bit
// depending upon architecture), which is why there is a union overlaying the 32 bit n32 over
// the actual data that the program uses, Data.
if (__sync_bool_compare_and_swap(_GlobalFoo.n32, Old.n32, New.n32))
break; // successfully changed
// if we get here, the global was changed by another thread, so we just loop back, get the new value
// and try again.
} // concurrency loop
}
Проницательные читатели могут подумать, что строка "Old.n32 = _GlobalFoo.n32;" может скопировать мусор в гонке, если компилятор выбрал неатомарный способ выполнить копирование. Однако __sync_bool_compare_and_swap просто потерпит неудачу из-за плохой копии текущего состояния, поэтому никакого вреда не будет.
веселит.