5

fork and pthread_create will return a process id or thread id.

But I don't know the value range of these ids.

Now I want to make a lookup table, in each entry there is a item/field for thread id. the structure of each entry is like:

 typedef struct {
   int seq;
   pthread_t tid;
   ...
 } entry_t;

I want to assign a value to an invalid tid to an entry when I don't get the tid of a thread(soon this field will be filled with a valid one, but before that the fill function will check whether the pid is valid or not). so, what is the value range of thread and process id?

unkulunkulu
  • 11,576
  • 2
  • 31
  • 49
misteryes
  • 2,167
  • 4
  • 32
  • 58
  • 1
    `pthread_create()` returns 0 or an error number; it sets the `pthread_t` structure that is passed into it via a pointer, but there's no documented structure for the `pthread_t` type. The PIDs returned by `fork()` are variants on the theme of `int`; they are 32-bit numbers, though all 32-bits are seldom used (but more than 16 of the bits are used). Linux has a `gettid()` function to return a thread ID; the return type is `pid_t`, the same as `fork()` and `getpid()`. It is not a standard function (and was added in kernel 2.4.11 according to the docs I'm looking at). – Jonathan Leffler May 17 '13 at 00:24
  • is it possible that `tid` = 0? – misteryes May 17 '13 at 00:39
  • @misteryes: Please be aware that the value returned by `gettid()` (tid) has nothing to do with the value written the first parameter by a successful call to `pthread_create()`. – alk May 17 '13 at 11:11

4 Answers4

8

The pthread_t type is completely opaque. You can only compare it for equality with the pthread_equal function, and there is no reserved value distinct from any valid thread id, though such a value will probably be added to the next version of the POSIX standard. As such, you'll need to store a second field alongside the thread id to track whether it's valid or not.

R.. GitHub STOP HELPING ICE
  • 208,859
  • 35
  • 376
  • 711
  • maybe 0 could be a distinct value? – misteryes May 17 '13 at 00:21
  • 0 is not even necessarily a value since `pthread_t` is not specified to be a scalar type. It could be a structure or union. The reserved value proposed for addition to POSIX would be an opaque macro that's only to be used for assignment and passing to `pthread_equal`. – R.. GitHub STOP HELPING ICE May 17 '13 at 00:39
  • I'm just afraid if I put `0` in the field, and then there is really a valid tid = 0, then there is a conflict. Because I have a timeout, when the timeout is reached, I will judge whether the tid is still 0, if it is I will delete it. But if there is really a valid `tid=0`, then my deletion is wrong! – misteryes May 17 '13 at 01:00
  • 1
    I told you putting 0 is not a portable solution. It will probably work for common threads implementations on Linux, but will not work in general. Use a separate field to flag whether you have a valid thread id. – R.. GitHub STOP HELPING ICE May 17 '13 at 02:10
  • See http://udrepper.livejournal.com/16844.html for a practical example of using pointers as thread identifiers. – loreb May 17 '13 at 14:13
  • Can I just call the `pthread_kill(tid, 0)` to check the validity of the tid value? – Mingliang Liu Oct 18 '13 at 13:07
  • 1
    @liuml07: No. Passing an invalid thread id to `pthread_kill` invokes undefined behavior. If you're lucky, it crashes your application. If you're unlucky, it may give you the wrong answer or worse. – R.. GitHub STOP HELPING ICE Oct 20 '13 at 04:06
3

The max value of pid is changeable, in default it is 32768, which is the size of the max value of short int.And, it can compatible with UNIX of early version.

You can see and change it in /proc/sys/kernel/pid_max.

BTW,

Process ID 0 is usually the scheduler process and is often known as the swapper. No program on disk corresponds to this process, which is part of the kernel and is known as a system process. Process ID 1 is usually the init process and is invoked by the kernel at the end of the bootstrap procedure. The program file for this process was /etc/init in older versions of the UNIX System and is /sbin/init in newer versions. This process is responsible for bringing up a UNIX system after the kernel has been bootstrapped. --APUE

The tid has significance only within the context of the process to which it belongs. In different famlies of UNIX, the pthread_t is not the same type,such as

Linux 2.4.22 uses an unsigned long integer for the pthread_t data type. Solaris 9 represents the pthread_t data type as an unsigned integer. FreeBSD 5.2.1 and Mac OS X 10.3 use a pointer to the pthread structure for the pthread_t data type. --APUE

So you can't simply tell its scope .

But threads_max presents how many threads in a process at most,you can see and change it in /proc/sys/kernel/threads-max.

vvy
  • 1,963
  • 13
  • 17
  • this means I can use pid=0 to indicate that it is not valid, but I can't use `tid=0`... – misteryes May 17 '13 at 09:48
  • @misteryes if tid is a pointer to the pthread structure, tid=0 means tid = NULL, which is invalid.You'd better check the type of tid in your system first. – vvy May 17 '13 at 12:23
  • Note that on non-Linux systems, the PID may not be limited to 32K (as a specific example, on Mac OS X, it wraps after PID = 99999). That doesn't invalidate this answer (the question is tagged Linux), but be cautious. My recollection is of seeing 6-digit PIDs on AIX, but I don't have access to AIX to confirm that. – Jonathan Leffler May 17 '13 at 14:57
  • Do not use pthread_t for this. This is thread descriptor of thread in pthreads library, like HANDLE in windows, which they names as some "thread id". More accurately "this is internal library value". You do not know which handle values are reserved inside library. Values may be equal to TID in system, or they may not be equal, they can be some index in some array inside library for example. You should use Thread ID of your thread for this. For get Thread ID you can use syscall(SYS_gettid). It will be equal to TID's in in htop. As @vvy wrote Process ID 0 usually is scheduler, 1 is init. – Alexander Symonenko Apr 02 '19 at 09:08
2

As others pointed out there is not value defined which indicates an invalid pthread-id.

One approach to get around this might be to mod your structure describing a thread like so:

typedef struct {
  int seq;
  pthread_t pthread;
  int pthread_is_valid; /* set this to 0 on initialisation of the structure 
                          and change it be 1 if pthread_create() was successfull. */
  ...
} entry_t;

Also I recommend to not call the value set by pthread_create()'s first parameter tid, as this cause name ambiguousness with what is retuned by gettid(), which under Linux actually is a process id.


As invalid process id -1 should do.

alk
  • 69,737
  • 10
  • 105
  • 255
0

My opinion why can't you track invalid thread id by assigning defined error value to tid itself. As you are making look up table, size may constraint if you keep add more members to struct when table grows.

/* Thread identifiers */ typedef unsigned long int pthread_t;

While checking pthread_create result, probably you assign your own defined error value .

Ex: pthread_create fail - assign say -ve value to tid . so while lookup you can validate checking your own #define -ve value.