Проблема с очисткой кэша при сборке выпуска

#c #cpu

#c #процессор

Вопрос:

Я вижу странную проблему в этом коде:

 namespace{
std::vector<int> my_vect;
}

thread1:
    sleep(5);
    my_vect.push_back(1);

main_thread:
    while(my_vect.empty());
    //do something
    return;
  

при сборке в debug все работает так, как ожидалось. При выпуске цикл while никогда не завершается…

Когда я перешел на цикл while с занятого ожидания на:

 while(my_vect.empty())
{
  sleep(1);
}
  

Созданный релиз снова начал работать.

Есть идеи, почему это может произойти?

Комментарии:

1. Почему мой вопрос отклонен?

2. Без какой-либо синхронизации ваша программа содержит гонку данных , что приводит к неопределенному поведению. Исправьте свой код, и проблема исчезнет.

3. @Blastfurnace, это исчезло, но я не понимаю почему… Я думал о том, что даже если цикл while обнаружил неверное значение для 1 итерации, мне все равно. На следующей итерации он будет действительным… Это неверное предположение? если да, то что не так с этой логикой?

4. @Kam, ты имел в виду «очистку кэша»?

5. @Kam: это предположение неверно. Гонка данных приводит к неопределенному поведению, точка. Вы не можете достоверно рассуждать о коде в его нынешнем виде, а стандарт C не определяет, может ли он выполняться или как он может выполняться. Нет гарантии, в каком состоянии находится вектор во время push_back() выполнения. Вы не можете писать параллельный код, подобный этому, и просто надеяться, что это сработает.

Ответ №1:

Да: несинхронизированный доступ к общей переменной является неопределенным поведением, и может произойти что угодно. Ваше наблюдаемое поведение не является особенно необычным.

Комментарии:

1. Не могли бы вы уточнить?

2. @Kam: Это довольно базовые знания. Возьмите любую книгу по многопоточному программированию, и она скажет вам не делиться переменными, если

3. Я знаю, как работает синхронизация 🙂 Я думал о том, что даже если цикл while обнаружил неверное значение для 1 итерации, мне все равно. На следующей итерации он будет действительным… Это неверное предположение? если да, то что не так с этой логикой?

4. компилятор в основном оптимизирует его для if (my_vect.empty()) {while(true);}

5. @Erbureth Вы не возражаете против вашего комментария в ответе и, пожалуйста, дайте мне знать, как вы это поняли? 🙂