errno в многопоточной реализации

Использовать errno в многопоточном приложении http://www.cplusplus.com/reference/cerrno/errno/ указывает, что это должно быть реализовано локально в каждом потоке. Что это значит?

2

Решение

errno должно быть thread-local, В каждом thread Значение этой переменной может быть разным.

что это должно быть локально реализовано в каждом потоке

Это не ваша обязанность осуществлять errno как thread_local переменная. Это работа для разработчиков компиляторов.

От cppreference.com


errno — макрос препроцессора, используемый для индикации ошибок.
Он расширяется до локально модифицируемого потока lvalue типа int. (начиная с C ++ 11)

Просто в компиляторах C ++ 11 этот код никогда не должен утверждать

#include <iostream>
#include <cerrno>
#include <thread>
#include <cassert>

int g_errno = 0;

void thread_function()
{
errno = E2BIG;
g_errno = errno;
}

int main()
{
errno = EINVAL;
std::thread thread(thread_function);
thread.join();
assert(errno != g_errno && "not multithreaded");
}
3

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

Исторически, errno был общий переменная типа int — т. е. каждый модуль принес свое собственное определение, и компоновщик отвечал за их объединение. Так что программы просто заявлены int errno; глобально и имел рабочее определение.

Это ломается в многопоточных средах, потому что есть только одна переменная. Таким образом, errno.h Теперь необходимо определить что-то, что является именующий intи программы не должны определять свои errno,

Библиотека GNU C, например, определяет что-то похожее на

#define errno (*(__errno_location()))

где __errno_location() это встроенная функция, которая вычисляет адрес локального потока errno,

Все это не имеет отношения к приложению, за исключением того, что это ошибка, чтобы определить свой собственный errno,

3

Это означает, что каждый поток должен иметь свой собственный экземпляр errno переменная

Реализация может легко достичь этого, используя что-то вроде:

int __thread errno;

__thread является расширением gcc, которое гарантирует, что переменная является локальной для потока (поэтому один поток не может перезаписать другой экземпляр переменной для другого потока)

Как пользователь errno, вам не нужно беспокоиться об этом. Вам даже не нужно беспокоиться о том, что errno, возможно, был предварительно изменен другим потоком.

0
По вопросам рекламы [email protected]