Повторно входящие функции не полагаются на глобальные переменные, которые отображаются в заголовках библиотеки C. Возьмем strtok () против strtok_r (), например, в C.
Некоторым функциям требуется место для хранения «незавершенного производства», повторяющиеся функции позволяют вам указывать этот указатель в собственном хранилище потока, а не в глобальном. Поскольку это хранилище является исключительным для вызывающей функции, оно может быть прервано и повторно введено (повторно входящее), и поскольку в большинстве случаев взаимное исключение за пределы того, что реализует функция, не требуется для этой работы, они часто считаются потокобезопасными . Это, однако, не гарантируется по определению.
errno, однако, это немного другой случай в системах POSIX (и, как правило, является странностью в любом объяснении того, как все это работает):)
Короче говоря, реентерабельный часто означает потокобезопасный (как в «используйте реентерабельную версию этой функции, если вы используете потоки»), но потокобезопасность не всегда означает реентерабельный задний ход). Когда вы смотрите на безопасность потоков, параллелизм - это то, о чем вы должны думать. Если для использования функции необходимо предоставить средства блокировки и взаимного исключения, то эта функция не является поточно-ориентированной.
Но не все функции нужно проверять ни для того, ни для другого. malloc()
не нуждается в повторном входе, он не зависит от чего-либо, выходящего за рамки точки входа для любого данного потока (и сам по себе является потокобезопасным).
Функции, которые возвращают статически распределенные значения, не поточно-безопасны без использования мьютекса, фьютекса или другого атомного механизма блокировки. Тем не менее, им не нужно возвращаться, если они не будут прерваны.
то есть:.
static char *foo(unsigned int flags)
{
static char ret[2] = { 0 };
if (flags & FOO_BAR)
ret[0] = 'c';
else if (flags & BAR_FOO)
ret[0] = 'd';
else
ret[0] = 'e';
ret[1] = 'A';
return ret;
}
Итак, как вы можете видеть, использование нескольких потоков, которое без какой-либо блокировки, было бы катастрофой ... но не имеет смысла возвращаться. Вы столкнетесь с этим, когда на какой-то встроенной платформе динамически выделенная память будет табу.
В чисто функциональном программировании повторное поступление часто не не подразумевает потокобезопасность, это будет зависеть от поведения определенных или анонимных функций, передаваемых в точку входа в функцию, рекурсии и т. Д.
Лучший способ поставить «потокобезопасный» - это безопасный для одновременного доступа , что лучше иллюстрирует необходимость.