Есть ли условия гонки в образце «защелки» в N3600?

Для включения в C ++ 14 (он же C ++ 1y) предложены некоторые новые примитивы синхронизации потоков: защелки и барьеры. Предложение

Это звучит как хорошая идея, и сэмплы делают его очень удобным для программистов. К сожалению, я думаю, что пример кода вызывает неопределенное поведение. В предложении говорится о latch::~latch():

Уничтожает защелки. Если защелка разрушена, в то время как другие темы находятся в wait()или призываем count_down(), поведение не определено.

Обратите внимание, что это говорит «в wait()«а не» заблокирован в wait()«, как описание count_down() использует.

Затем предоставляется следующий образец:

Пример второго варианта использования показан ниже. Нам нужно загрузить данные и затем обработать их, используя несколько потоков. Загрузка данных связана с вводом / выводом, тогда как запуск потоков и создание структур данных связаны с процессором. Запустив их параллельно, можно увеличить пропускную способность.

void DoWork()
{
latch start_latch(1);
vector<thread*> workers;
for (int i = 0; i < NTHREADS; ++i) {
workers.push_back(new thread([&] {
// Initialize data structures. This is CPU bound.
...
start_latch.wait();
// perform work
...
}));
}
// Load input data. This is I/O bound.
...
// Threads can now start processing
start_latch.count_down();
}

Разве нет условия гонки между нитями, просыпающимися и возвращающимися из wait(), а разрушение защелки когда оно выходит за рамки? Кроме того, все thread объекты просочились. Если планировщик не запускает все рабочие потоки раньше count_down возвращается и start_latch объект выходит из области видимости, тогда я думаю, что неопределенное поведение приведет к. Предположительно, решение состоит в том, чтобы перебрать вектор и join() а также delete все рабочие потоки после count_down но прежде чем вернуться.

  1. Есть ли проблема с примером кода?
  2. Согласны ли вы с тем, что в предложении должен быть приведен полный правильный пример, даже если задача очень простая, чтобы рецензенты могли увидеть, как будет выглядеть использование?

Примечание. Возможно, один или несколько рабочих потоков еще не начали ждать и поэтому будут вызывать wait() на разрушенной защелке.


Обновление: появилась новая версия предложения, но типичный пример не изменился.

6

Решение

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

Любая реализация, которая позволяет блокировать потоки в wait (), почти наверняка будет включать в себя некоторую переменную условия, и уничтожение защелки, пока поток еще не вышел, wait () потенциально не определено.

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

Алэсдэйр

4

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector