Функції повторного вступу не покладаються на глобальні змінні, які виставляються в заголовках бібліотеки C. .. візьмемо strtok () проти strtok_r (), наприклад, у C.
Деякі функції потребують місця для зберігання "незавершеного виробництва", функції повторного входу дозволяють вказати цей покажчик у власному сховищі потоку, а не в глобальному. Оскільки це сховище призначене виключно для функції, що викликає, його можна перервати та повторно ввести (повторно ввійти), і оскільки в більшості випадків взаємне виключення, що перевищує те, що реалізує функція, не потрібне для роботи, їх часто вважають нитка безпечна . Однак це не гарантується визначенням.
errno, однак, дещо інший випадок у системах POSIX (і, як правило, є дивним у будь-якому поясненні того, як все це працює) :)
Коротше кажучи, реентерант часто означає безпечний для потоку (як у "використовуйте версію цієї функції, що реагує, якщо ви використовуєте потоки"), але безпечний для потоку не завжди означає повторний вхід (або зворотний). Коли ви дивитесь на безпеку потоків, паралельність - це те, про що вам слід подумати. Якщо вам потрібно надати засіб блокування та взаємного виключення для використання функції, тоді функція за своєю суттю не є безпечною для потоків.
Але не всі функції потрібно перевіряти на будь-яку з них. malloc()
не потребує повторного входу, це не залежить ні від чого, що виходить за рамки точки входу для будь-якого потоку (і саме є потокобезпечним).
Функціями, які повертають статично розподілені значення, є не безпечними для потоку без використання mutex, futex або іншого атомного механізму блокування. Тим не менше, їм не потрібно повертатися, якщо їх не збираються переривати.
тобто:
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;
}
Отже, як ви можете бачити, використання декількох потоків, що без якогось блокування буде катастрофою .. але це не має на меті бути повторним учасником. Ви натрапите на це, коли динамічно розподілена пам’ять є табу на якійсь вбудованій платформі.
У чисто функціональному програмуванні реентант часто цього не робить означає безпеку потоку, це залежатиме від поведінки визначених або анонімних функцій, переданих точці входу функції, рекурсії тощо.
Кращий спосіб забезпечити безпеку потокового зв'язку для одночасного доступу , що краще ілюструє потребу.