Барьерные тупики в GCC 11.1.0

#c #multithreading #c 20 #race-condition #barrier

Вопрос:

Рассмотрим следующий код на C :

 #include <barrier>
#include <iostream>
#include <string>
#include <thread>

int main() 
{
  constexpr unsigned N = 2;
  std::barrier barrier(N);
  auto const run = [amp;barrier]() 
  {
    std::string buff;
    for(unsigned i = 0; i < 1000; i  ) 
    {
      std::cout << ((buff = "A ")   std::to_string(i)   "n");
      barrier.arrive_and_wait();
      std::cout << ((buff = "B ")   std::to_string(i)   "n");
      barrier.arrive_and_wait();
      std::cout << ((buff = "C ")   std::to_string(i)   "n");
    }
  };

  std::thread ts[N];
  for(unsigned j = 0; j < N; j  ) ts[j] = std::thread(run);
  for(unsigned j = 0; j < N; j  ) ts[j].join();
}
 

Когда я компилирую/запускаю его Clang 12.0.1 , он ведет себя так, как ожидалось.
Такое же ожидаемое поведение, когда я использую GCC 11.1 (C 20) доступные онлайн по адресу en.cppreference.com.
Однако, когда я использую свой локальный , он часто блокируется после печати следующих строк GCC 11.1.0 :

 A 0
A 0
B 0
B 0
C 0
A 1
 
  1. Является ли этот код четко определенным?
  2. Предполагается ли, что это не приведет к тупику?

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

1. @463035818_is_not_a_number Я думаю, что OP означает Coliru, который используют кнопки «Запустить этот код» в cppreference.

2. Идея попытаться найти проблему: используйте osyncstream вместо записи непосредственно в std::cout и добавьте функцию завершения в std::barrier . Возможно, это покажет что-то интересное. Приготовил его здесь :

3. Коша: Моя версия вашей программы также зависала, когда вы пробовали ее с вашим локальным GCC 11.1.0?

4. @TedLyngmo Я несколько раз пробовал это с помощью GCC 11.1.0. Он не генерировал никаких выходных данных (Ctrl C примерно через 10 секунд бездействия). Попытался скомпилировать его с помощью Clang, но syncstream файл не был найден.

5. @Koosha Хорошо, возможно, версия clang слишком старая. Я получаю первую ошибку с clang 12.0.0 <barrier> , хотя нет <syncstream> . С clang 12.0.1 программа работает нормально.