#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 Вы не возражаете против вашего комментария в ответе и, пожалуйста, дайте мне знать, как вы это поняли? 🙂