Безопасность потока сообщений MSVC
Является ли errno
в MSVC потокобезопасным?
В соответствии с ответами в этом вопросе POSIX требует, чтобы errno
был потокобезопасным. Но MSVC, вероятно, не совместим с POSIX и MSDN ничего не говорит о безопасности потоков. MSDN противоречиво упоминает, что errno
объявлен как extern int errno;
, но также как #define errno (*_errno())
Ответы
Ответ 1
Хотя MSVC определенно не совместим с POSIX, errno
реализуется в среде выполнения MSVC (по крайней мере, с MSVC2008) в потоковом режиме.
Несмотря на то, что в документации указано, что она extern int errno
, она фактически реализована как #define
для функции, которая позволяет навязывать потоки. Если вы выполните эту функцию в окне разборки, ясно, что используется локальное хранилище потоков.
К сожалению, я не могу указать на официальную документацию, подтверждающую это, но это жизнь!
Ответ 2
Я не могу найти нигде на сайте MSDN, где это обсуждается. Однако многие функции, которые возвращают статические буферы, уже являются потокобезопасными в MSVC (т.е. Возвращают указатели на потоковые локальные буферы). Поэтому было бы удивительно, если бы errno не был потокобезопасным.
Все файлы заголовков MSVC имеют следующее определение:
#ifndef _CRT_ERRNO_DEFINED
#define _CRT_ERRNO_DEFINED
_CRTIMP extern int * __cdecl _errno(void);
#define errno (*_errno())
errno_t __cdecl _set_errno(_In_ int _Value);
errno_t __cdecl _get_errno(_Out_ int * _Value);
#endif /* _CRT_ERRNO_DEFINED */
И небольшая тестовая программа показала, что 2 потока, устанавливающие errno, по крайней мере не влияют друг на друга.
Поэтому я бы сказал, что безопасно предположить, что errno является потокобезопасным (хотя, вероятно, нет, если вы ссылаетесь на единственный поток CRT)