- A reentrant function can be called simultaneously by multiple threads provided that each invocation of the function references unique data.
- A thread-safe function can be called simultaneously by multiple threads when each invocation references shared data. All access to the shared data is serialized.
Re-entrant functions do not rely on global
variables that are exposed in the C library headers .. take strtok() vs
strtok_r() for example in C.
Some functions need a place to store a 'work in progress' , re-entrant functions allow you to specify this pointer within the thread's own storage, not in a global.
errno, however, is a slightly different case on POSIX systems :)
In short, reentrant often means thread safe (as in "use the reentrant version of that function if you're using threads"), but thread safe does not always mean re-entrant. Some functions do not rely on some exposed global variable that other threads could clobber.
malloc() has no need to be reentrant, it does not depend on anything out of the scope of the entry point for any given thread.
Functions that return statically allocated values are not thread safe without the use of a mutex, futex, or other atomic locking mechanism. Yet, they don't need to be reentrant.
i.e.:
In purely functional programming, reentrant often doesn't imply thread safe, it would depend on the behavior of defined or anonymous functions passed to the function entry point, recursion, etc.
A better way to put 'thread safe' is safe for concurrent access , which better illustrates the need.
Some functions need a place to store a 'work in progress' , re-entrant functions allow you to specify this pointer within the thread's own storage, not in a global.
errno, however, is a slightly different case on POSIX systems :)
In short, reentrant often means thread safe (as in "use the reentrant version of that function if you're using threads"), but thread safe does not always mean re-entrant. Some functions do not rely on some exposed global variable that other threads could clobber.
malloc() has no need to be reentrant, it does not depend on anything out of the scope of the entry point for any given thread.
Functions that return statically allocated values are not thread safe without the use of a mutex, futex, or other atomic locking mechanism. Yet, they don't need to be reentrant.
i.e.:
So, as you can see, having multiple threads use that without some kind of locking would be a disaster .. but it has no purpose being re-entrant. You'll run into that when dynamically allocated memory is taboo on some embedded platform.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; }
In purely functional programming, reentrant often doesn't imply thread safe, it would depend on the behavior of defined or anonymous functions passed to the function entry point, recursion, etc.
A better way to put 'thread safe' is safe for concurrent access , which better illustrates the need.
沒有留言:
張貼留言