Atomic 64-битная запись с помощью GCC

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

Немного почитав, я пришел к пониманию, что я должен иметь возможность атомарно устанавливать значение 64-битного int в 64-битной системе 1 .

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

bool switcher = false;

while(true)
{
    if (switcher)
        foo = a;
    else
        foo = b;
    switcher = !switcher;
}

И другой поток, который проверял бы значение foo :

while (true)
{
    __uint64_t blah = foo;
    if ((blah != a) && (blah != b))
    {
        cout << "Not atomic! " << blah << endl;
    }
}

Я установил a = 1844674407370955161; и b = 1144644202170355111; . Я запускаю эту программу и не получаю предупреждения, что blah не является a или b .

Отлично, похоже, это, вероятно, атомарная запись. ..но затем я изменил первый поток, чтобы установить a и b напрямую, вот так:

bool switcher = false;

while(true)
{
    if (switcher)
        foo = 1844674407370955161;
    else
        foo = 1144644202170355111;
    switcher = !switcher;
}

Повторно запускаю, и вдруг:

Not atomic! 1144644203261303193
Not atomic! 1844674406280007079
Not atomic! 1144644203261303193
Not atomic! 1844674406280007079

Что изменилось? В любом случае я присваиваю большое число foo - компилятор обрабатывает постоянное число по-другому, или я все неправильно понял?

Спасибо!


1: Документация по процессору Intel, раздел 8.1, Гарантированные атомарные операции

2: Список разработчиков GCC, в котором обсуждается, что GCC не гарантирует этого в документации, но ядро ​​и другие программы полагаются на него

12
задан Frederik 10 March 2011 в 10:52
поделиться