У меня была та же проблема с NetBeans 8.1 в Linux Mint 17.2, и я нашел решение (во время установки выбрал неправильный каталог JDK).
Если не удается найти совместимую установку JDK, вам может понадобиться чтобы вручную добавить путь к каталогу установки JDK, выполнив следующее:
https://netbeans.org/community/releases/81/install.html#install_zip
#include <iostream>
#include <thread>
#include <unistd.h>
using namespace std;
bool checkValue = false;
int main()
{
std::thread writer([&](){
sleep(2);
checkValue = true;
std::cout << "Value of checkValue set to " << checkValue << std::endl;
});
std::thread reader([&](){
while(!checkValue);
});
writer.join();
reader.join();
}
Как только интервьюер, который также считал, что volatile бесполезен, со мной спорил, что оптимизация не вызовет никаких проблем и относится к разным ядрам, имеющим отдельные строки кеша и все это (на самом деле не понимало, что именно он ссылаясь на). Но этот фрагмент кода, скомпилированный с -O3 в g ++ (g ++ -O3 thread.cpp -lpthread), показывает неопределенное поведение. В основном, если значение устанавливается перед проверкой while, оно работает нормально, а если нет, оно переходит в цикл, не утруждая себя извлечением значения (которое фактически было изменено другим потоком). В принципе, я считаю, что значение checkValue получает только один раз в регистр и никогда не проверяется снова при самом высоком уровне оптимизации. Если его набор равен true перед выборкой, он работает нормально, и если он не переходит в цикл. Пожалуйста, исправьте меня, если я ошибаюсь.
Вам нужна летучая и, возможно, блокировка.
volatile сообщает оптимизатору, что значение может изменяться асинхронно, таким образом
volatile bool flag = false;
while (!flag) {
/*do something*/
}
будет считывать флаг каждый раз вокруг цикла.
Если вы отключите оптимизацию или сделаете каждую переменную изменчивой, программа будет вести себя одинаково, но медленнее. «Я знаю, что вы, возможно, просто прочитали его и знаете, что он говорит, но если я скажу, прочитайте его, тогда прочитайте его.
Блокировка является частью программы. Итак, кстати, если вы реализуете семафоры, то между прочим они должны быть неустойчивыми. (Не пытайтесь, это сложно, возможно, потребуется небольшой ассемблер или новый атомный материал, и это уже сделано.)
volatile
не очень полезно даже в этом случае. Но ожидание - это иногда полезная техника.
– jalf
5 January 2011 в 21:05
Short & amp; быстрый ответ: volatile
(почти) бесполезен для платформо-агностического многопоточного программирования приложений. Он не обеспечивает никакой синхронизации, не создает забора памяти и не обеспечивает порядок выполнения операций. Он не делает операции атомарными. Это не делает ваш код волшебным потоком в безопасности. volatile
может быть единственным непонятым средством во всех C ++. См. этот , этот и этот для получения дополнительной информации о volatile
С другой стороны, volatile
имеют некоторое применение, которое может быть не столь очевидным. Его можно использовать так же, как и использовать const
, чтобы помочь компилятору показать вам, где вы можете ошибиться при доступе к некоторому совместно используемому ресурсу незащищенным способом. Это использование обсуждается Александреску в этой статье . Тем не менее, в основном это используется система типа C ++, которая часто рассматривается как средство и может вызывать Undefined Behavior.
volatile
специально предназначалось для использования при взаимодействии с аппаратным обеспечением с отображением памяти, обработчиков сигналов и команды машинного кода setjmp. Это делает volatile
прямо применимым к программированию на системном уровне, а не к нормальному программированию на уровне приложений.
В стандарте C ++ 2003 не говорится, что volatile
применяет любую семантику Acquire или Release для переменных. Фактически, стандарт полностью умалчивает обо всех вопросах многопоточности. Однако определенные платформы действительно применяют семантику Acquire и Release в переменных volatile
.
Стандарт C ++ 11 теперь делает подтверждают многопоточность непосредственно в модели памяти и lanuage, и она предоставляет библиотечные возможности для решения этой проблемы независимо от платформы. Однако семантика volatile
все еще не изменилась. volatile
все еще не является механизмом синхронизации. Bjarne Stroustrup говорит так же в TCPPPL4E:
Не используйте
volatile
, за исключением низкоуровневого кода, который напрямую связан с оборудованием.Не предполагайте, что
blockquote>volatile
имеет особое значение в модели памяти. Это не. Это не так, как в некоторых более поздних языках - механизм синхронизации. Чтобы получить синхронизацию, используйтеatomic
,mutex
илиcondition_variable
.[/ End update]
Вышеприведенное все применимо к C ++ самого языка, как это определено Стандартом 2003 года (и теперь стандартом 2011 года). Однако некоторые конкретные платформы добавляют дополнительные функциональные возможности или ограничения на то, что делает
volatile
. Например, в MSVC 2010 (по крайней мере) семантика получения и выпуска применяется к определенным операциям в переменныхvolatile
. Из MSDN :При оптимизации компилятор должен поддерживать упорядочение среди ссылок на изменчивые объекты, а также ссылки на другие глобальные объекты. В частности,
Запись в изменчивый объект (volatile write) имеет семантику Release; ссылка на глобальный или статический объект, который возникает до того, как запись в энергозависимый объект в последовательности команд произойдет до этой изменчивой записи в скомпилированном двоичном файле.
Чтение изменчивого объекта (изменчивое чтение) имеет Получить семантику; ссылка на глобальный или статический объект, который возникает после считывания энергозависимой памяти в последовательности команд, будет возникать после этого изменчивого чтения в скомпилированном двоичном файле.
blockquote>Однако вы можете принять к сведению факт, что если вы будете следовать приведенной выше ссылке, в комментариях будет высказано мнение о том, применимы ли в этом случае семантика на самом деле или нет.
volatile
, это потому, что вы стояли на плечах людей, которые использовали volatile
для реализации библиотек потоков.
– Ben Jackson
29 December 2010 в 23:19
volatile
на самом деле делает в C ++. Что @John сказал правильный i>, конец истории. Он не имеет ничего общего с кодом приложения или кодом библиотеки, или «обычным». vs "богоподобные всезнающие программисты" в этом отношении. volatile
не требуется и бесполезен для синхронизации между потоками. Библиотеки потоков не могут быть реализованы с точки зрения volatile
; он все равно должен полагаться на детали, зависящие от платформы, и когда вы полагаетесь на них, вам больше не нужно volatile
.
– jalf
30 December 2010 в 00:40
Летучие иногда полезны по следующей причине: этот код:
/* global */ bool flag = false;
while (!flag) {}
оптимизирован gcc:
if (!flag) { while (true) {} }
Что явно неверно, если флаг написан к другой теме. Обратите внимание, что без этой оптимизации механизм синхронизации, вероятно, работает (в зависимости от другого кода могут потребоваться некоторые барьеры памяти) - нет необходимости в мьютексе в 1 сценарии потребления 1-го производителя.
В противном случае ключевое слово volatile слишком странно, чтобы его можно было использовать - он не обеспечивает каких-либо гарантий резервирования памяти во время волатильных и энергонезависимых доступов и не обеспечивает каких-либо атомных операций - то есть вы не получаете помощи от компилятора с ключевым словом volatile, кроме кэширования отключенных регистров.
volatile
не препятствует переупорядочению доступа к памяти. volatile
доступа не будут переупорядочены по отношению друг к другу, но они обеспечивают no i> гарантию о переупорядочении по отношению к объектам, отличным от volatile
, и поэтому они в основном бесполезны в качестве флагов, поскольку Что ж.
– jalf
30 December 2010 в 00:42
volatile
.
– jalf
5 January 2011 в 21:02
while (work_left) { do_piece_of_work(); if (cancel) break;}
, если отмена переупорядочена в пределах цикл, логика по-прежнему действительна. У меня был фрагмент кода, который работал аналогично: если основной поток хочет завершить работу, он устанавливает флаг для других потоков, но это не так ...
– Dan
13 February 2011 в 15:03
volatile
? Да, этот код UB - но это UB сvolatile
. – David Schwartz 11 July 2018 в 07:50