Будет ли получение текущей даты/времени потокобезопасным в C++20?


Короткий Вопрос

Вплоть до C++17, C++ не предоставляет потокобезопасного способа получения текущего времени или даты. Будет ли это исправлено в C++20?

Длинный Вопрос

Единственный переносимый способ получить текущее время и дату-это использовать функции std::gmtime или std::localtime. Остатки от ранних дней C, эти функции преобразуют заданное время с момента реализации определенной эпохи в календарное время (например, 1515153600 в Пт, 05 янв 2018 12: 00: 00 GMT). Единственным недостатком, однако, является то, что эти функции возвращают указатель на внутреннюю статическую переменную и не являются threadsafe. Еще хуже то, что эта статическая переменная может быть общей для всех связанных функций, таких как std::gmtime, std::localtime и std::ctime, и может быть перезаписана при каждом вызове любой из этих функций. Поэтому, если вы используете потоки и хотите регулярно проверять время, вы рискуете гонками данных и неопределенным поведением.

Ясно течение стандарт в этом отношении нарушен. Есть ли какие-либо усилия комитета по стандарту C++, чтобы исправить эту ситуацию, и насколько вероятно, что это будет включено в C++20?

1 7

1 ответ:

Библиотека дат Говарда Хиннанта это то, что подходит для C++20. Он был предложен через p0355r4 и одобрен для C++20 в ноябре. 2017 год. Это потокобезопасно? К сожалению, ни в документации, ни в предложении, по-видимому, нет ясности по этому вопросу. Однако некоторые функции, такие как get_tzdb_list, явно называются "потокобезопасными". Ваш лучший вариант-спросить самого Хиннанта в чатеgitter . Однако обсуждение в Почему нет c++11 threadsafe альтернативы std:: localtime и std:: gmtime?, кажется, предполагает, что это потокобезопасно (хотя это никогда не было явно сказано). Как указывает Николь Болас , вы можете просто обернуть его за мьютекс.

Если это не так, вы можете снова получить гонки данных и, следовательно, неопределенное поведение. Если вы кодируете на больших проектах, где работа по кодированию разделена на команды, вы должны постоянно напоминать всем, что они не должны (!) используйте функции, предусмотренные стандартом C++, но используйте свои собственные обертка вместо этого (или риск неопределенного поведения).

На поверхностном уровне это то, для чего нужны обзоры кода. Facebook имеет эту проблему для младших разработчиков, где они продолжают делать одни и те же ошибки снова и снова. Если у вашей команды есть "странно повторяющиеся ошибки", вам нужно как-то их устранить (например, добавить проверки в linter: Clang приходит на ум).

На гораздо более прямом уровне, Google является воплощением этого. Проблема, с которой они столкнулись, заключалась в использовании старой коровы реализация string и переход на SSO-based string. Однако, поскольку они полагались на сторонние библиотеки, которые использовали COW-based string, они должны были поддерживать оба в своей кодовой базе. Говорить разработчикам, чтобы они использовали оболочку Google, было бесполезно. Решение, которое придумал разработчик, состояло в использовании Хака с inline namespaces. Немного экстремально, но если вы имеете дело с такой же большой кодовой базой, это может сделать трюк.