Why and in what sense is pthread_t an opaque type?
Asked Answered
L

2

7

Posts here on SO suggest that pthread_t is an opaque type, not a number, certainly not a thread index, that you shouldn't directly compare pthread_t's, etc. etc.

Questions:

  1. Why? Is there really the intent to support systems with no numeric IDs for threads? When the pthread_t implementation is simply

    typedef unsigned long int pthread_t;
    

    ?

  2. How? There's a comment before the above line, so it's actually

    /* Thread identifiers. The structure of the attribute type is not
       exposed on purpose.  */
    typedef unsigned long int pthread_t;
    

    in pthreadtypes.h what does that mean? What attribute type? Isn't this an index into some global table of threads?

Latinize answered 22/10, 2015 at 16:7 Comment(3)
Would that not depend on the underlying OS API? Nobody outside of an OS kernel wants to keep a global table of threads - it would not be reliable.Moise
@MartinJames: If that's the reason pthreads is like that, make your comment an answer... but - I would think that either the index is into the OS' table of threads, or into the library's table of threads when the OS doesn't expose one/have one.Latinize
FYI on practical real-world implementations it's actually a pointer, not an integer/index. Sometimes said pointer is stuffed into an integer type like unsigned long (this assumes ILP32 or LP64 model) for legacy compatibility reasons but the content is actually an address.Weiner
D
5

Is there really the intent to support systems with no numeric IDs for threads?

There are different types that could serve as numeric thread identifier. For example, on systems with limited resources an 8-bit thread identifier could be used instead of unsigned long.

The structure of the attribute type is not exposed on purpose.

The comment is not for pthread_t definition, but for the pthread_attr_t definition one line below:

typedef union
{
  char __size[__SIZEOF_PTHREAD_ATTR_T];
  long int __align;
} pthread_attr_t;

The comment states that char __size[__SIZEOF_PTHREAD_ATTR_T] is used in order to hide the content of the actual struct.

Isn't [pthread_t] an index into some global table of threads?

It does not have to be. The fact that the actual type is hidden allows an implementer to use any type that he wishes, including a pointer or a struct. Using a struct lets the implementer avoid using a global table of threads in the code of his library (OS would probably keep such table, though).

Dorr answered 22/10, 2015 at 16:45 Comment(1)
Well, the actual type is not really hidden, but, ok.Latinize
T
6

The POSIX standard allows pthread_t to be something more complex (such as a structure). See this previous question, especially the answer by @james-mcnellis. Money quote:

IEEE Std 1003.1-2001/Cor 2-2004, item XBD/TC2/D6/26 is applied, adding pthread_t to the list of types that are not required to be arithmetic types, thus allowing pthread_t to be defined as a structure.

UPDATE: Here are a few examples of more complex pthread_t definitions:

And here is an ancient (2007) justification of the pthread_t structure used in the pthreads library for Win32: https://sourceware.org/ml/pthreads-win32/2007/msg00056.html

Toilet answered 22/10, 2015 at 16:30 Comment(0)
D
5

Is there really the intent to support systems with no numeric IDs for threads?

There are different types that could serve as numeric thread identifier. For example, on systems with limited resources an 8-bit thread identifier could be used instead of unsigned long.

The structure of the attribute type is not exposed on purpose.

The comment is not for pthread_t definition, but for the pthread_attr_t definition one line below:

typedef union
{
  char __size[__SIZEOF_PTHREAD_ATTR_T];
  long int __align;
} pthread_attr_t;

The comment states that char __size[__SIZEOF_PTHREAD_ATTR_T] is used in order to hide the content of the actual struct.

Isn't [pthread_t] an index into some global table of threads?

It does not have to be. The fact that the actual type is hidden allows an implementer to use any type that he wishes, including a pointer or a struct. Using a struct lets the implementer avoid using a global table of threads in the code of his library (OS would probably keep such table, though).

Dorr answered 22/10, 2015 at 16:45 Comment(1)
Well, the actual type is not really hidden, but, ok.Latinize

© 2022 - 2024 — McMap. All rights reserved.