Post by Ronald Landheer-CieslakPost by Ronald Landheer-CieslakThe actual code will not have the assertion explicitly, because there
will be no way for me to store the thread ID somewhere in a
thread-safe manner: I'm (still) implementing a thread-local pointer. I
need to be able to count on the handle being returned for my thread to
be valid at all times - at least until the end of the thread's life.
Since your answer suggests you're using an existing thread library rather
than creating yoru own... why aren't you using the standard
thread-specific data instead of trying to invent your own "thread-local"
data mechanism? That IS what it's there for. Or is this more an academic
exercise?
What I need is a portable and transparent way to store data
local to a thread in an instance of a class that is not local to the
thread. The transparency means the code using my class must be able to
use it as any other (raw) pointer. That means that I can't just ask for
a key and hand it back to the user - the class must be able to handle
it's own keys internally. Hence, the easiest way would be to map the
pointer I'm storing against the thread itself - either by getting a
unique ID of the thread and mapping against that (which is what I do
for Windows) or by creating a unique ID from the handle of the thread
(because I can't use the handle itself to map against) and map against
the ID.
The problem is mainly that there isn't a portable way to store the key
one uses for thread-local storage anywhere that I'm sure I can get at
it from my thread: I can't hand it back to the user because he's not
expecting that, I can hardly put it in thread-local storage by itself
(as then I'd have YA key to point to the key). I can't expect to get
the same key each time I ask for a new one, I can't just put it on the
thread's stack because I don't know how long it will stay alive, etc.
The only way I see to do this is to map against something that is
unique and non-transient for the thread itself: either the ID (Windows)
or an ID I create (POSIX).
I'm not sure whether you don't understand thread-specific data, or whether
you haven't thoroughly explained your constraints. To me, this sounds like
thread-specific data would be a good fit for your requirements.
You create a thread-specific data key (pthread_key_create) ONCE; possibly
storing it as a "static" (class) member. Any object of that class can then
pass the key to pthread_setspecific() to set a thread-specific VALUE
(presumably a pointer) for the global KEY; and pthread_getspecific() to
retrieve the thread's value... which it can return to the caller for use as
a normal pointer. (Of course there are restrictions on what the caller
should be allowed to do with that pointer behind your back... but that
doesn't distinguish it from your model.)
I assume you actually want a unique per-thread value for each OBJECT of the
class, and that's just a little more complicated. You probably don't want
to create a new key with each object constructor, because POSIX allows for
a fixed number of keys and you might run out. (Though the assumption of
unlimited keys would just make your code slightly less portable, not
"wrong"... in POSIX terms, "conforming" but not "strictly conforming".) You
could instead use the single static key for the class, but make the value a
list (or hash table) of per-object values for that thread, which at least
would simplify (and speed) your lookup over doing everything yourself.
--
/--------------------[ ***@hp.com ]--------------------\
| Hewlett-Packard Company Tru64 UNIX & VMS Thread Architect |
| My book: http://www.awl.com/cseng/titles/0-201-63392-2/ |
\----[ http://homepage.mac.com/dbutenhof/Threads/Threads.html ]---/