С ++ 11 атомика.visibility и thread.join () / правильный способ остановить поток - PullRequest
0 голосов
/ 15 февраля 2019

Для каких (если есть?) STORE_ORDER & LOAD_ORDER гарантирует ли C ++ 11, что этот код выполняется за конечное время?

std::atomic<bool> a{false};
std::thread t{[&]{
  while(!a.load(LOAD_ORDER));
}};
a.store(true, STORE_ORDER);
t.join();

Я вижу две проблемы с этим:

Порядок памяти

Мне кажется, что с release & aquire компилятору и процессору разрешается переупорядочивать мой join (при условии, что он ведет себя как загрузка) до storeчто, конечно, сломало бы это.

Даже с memory_order_seq_cst, я не уверен, запрещено ли такое переупорядочение, потому что я не знаю, действительно ли join() выполняет какие-либо загрузки или сохранения.

Visibility

Если я правильно понял этот вопрос о memory_order_relaxed, то не гарантируется, что магазин с memory_order_relaxed станет видимым для других потоков за конечное время,Есть ли такая гарантия для любого другого заказа?

Я понимаю, что std::atomic - это атомарность и порядок в памяти, а не видимость.Но я не знаю никаких других инструментов в c ++ 11, которые могли бы мне здесь помочь.Нужно ли мне использовать инструмент для конкретной платформы, чтобы получить здесь гарантию правильности, и если да, то какую?


Чтобы сделать этот шаг еще дальше - если у меня есть конечность, было бы неплохо такжеесть обещание о скорости.Я не думаю, что стандарт C ++ дает такие обещания.Но есть ли какой-то компилятор или специфичный для x86 способ получить обещание, что хранилище станет видимым для другого потока быстро?


В заключение: я ищу способ быстро остановить работникапоток, который на самом деле гарантированно имеет это свойство.В идеале это не зависит от платформы.Но если у нас не может быть этого, существует ли оно хотя бы для x86?

1 Ответ

0 голосов
/ 16 февраля 2019

После еще нескольких поисков я нашел вопрос, идентичный моей части видимости, который получил четкий ответ : действительно такой гарантии нет - есть толькозапрос о том, что "реализации должны сделать атомарные хранилища видимыми для атомных нагрузок в течение разумного периода времени" .Стандарт не определяет, что означает «должен», но я приму нормальное значение, так что это не будет обязательным.Также не совсем понятно, что означает «разумный», но я бы предположил, что он явно исключает «бесконечный».

Это не совсем отвечает на вопрос об упорядочении памяти.Но если магазин будет заказан после join(), который может заблокироваться навсегда, магазин никогда не станет видимым для других потоков - что не будет «разумным количеством времени».

Так что пока стандартне требует, чтобы код в вопросе был действительным, он по крайней мере предполагает, что он должен быть действительным.В качестве бонуса фактически говорится, что это должно быть не только конечное время, но и несколько быстрое (или вполне разумное).

Это оставляет часть моего вопроса о решении для конкретной платформы: есть лиспецифичный для x86 способ написания запрошенного алгоритма, чтобы он гарантированно был правильным?

...