9

I'm trying to find a way to uniquely identify threads in a multi-process environment. I have a server that keeps track of the different processes connecting to it, some of which are multi-threaded and some of which are not. To identify the threads from multi-threaded connections I'm using the thread ID as a unique identifier (there will be a maximum of 1 multi-threaded process connected at any given time). My question is: is it possible the thread ID of one of these threads could be the same as the process ID of another processes running on the system?

Thanks in advance for the help!

HoldOffHunger
  • 18,769
  • 10
  • 104
  • 133
mgcleveland
  • 123
  • 2
  • 5

5 Answers5

13

The TID (as returned by the sys_gettid() system call) is unique across all threads on the system1, and for a single-threaded process the PID and TID are equal. This means that a TID will never clash with a PID from another process.


1. With the caveat that if PID namespaces are in use, TIDs and PIDs are only unique within the same PID namespace.
caf
  • 233,326
  • 40
  • 323
  • 462
  • Ok that is good information. Currently I'm using the `pthread_self()` function, but this only guarantees uniqueness __within__ the process. I think the `sys_gettid()` is the way to go, thanks! – mgcleveland Jan 03 '13 at 15:42
  • @mgcleveland: Note that this is Linux-specific, though. – caf Jan 04 '13 at 00:09
  • 1
    Here it says `gettid()` and not `sys_gettid()`. http://linux.die.net/man/2/gettid – Alexis Wilke Apr 22 '16 at 23:25
  • @AlexisWilke read the "Notes" section at the manpage you link. – Chris Stratton Apr 22 '16 at 23:34
  • @All, Note that the answer given by mux below is correct. I think. – andy May 18 '16 at 09:18
  • 2
    @andy: There is a difference between the Linux thread IDs returned by `SYS_gettid` (which are system-wide unique) and the POSIX thread IDs of type `pthread_t` (which are only guaranteed to be process-wide unique). – caf May 18 '16 at 13:19
9

According to the man page of pthreads the thread ID is unique within the creating process, so yes another thread or process could have the same ID. However, If it's unique within a process and a process ID is unique in the system then maybe you can use a combination of the two as a unique identifier.

Each of the threads in a process has a unique thread identifier (stored in the type pthread_t). This identifier is returned to the caller of pthread_create(3), and a thread can obtain its own thread identifier using pthread_self(3). Thread IDs are only guaranteed to be unique within a process.

Manuel Selva
  • 18,554
  • 22
  • 89
  • 134
iabdalkader
  • 17,009
  • 4
  • 47
  • 74
  • Thanks for your answer mux. I am familiar with that man page entry, however it doesn't specify conclusively whether or not the thread IDs within a process could intersect with the set of process IDs on the system. There is the hybrid approach you mention, but I'm trying to keep the value to one uint65_t data type, if at all possible. – mgcleveland Jan 02 '13 at 17:07
  • @mgcleveland if it's not guaranteed to be *unique system wide* then nothing keeps it from being reused as a PID, and that's the point. – iabdalkader Jan 02 '13 at 17:20
  • yep that's the assumption I'm working on. We currently have the implementation as described, but will likely have to modify it to something similar to what you suggested. Thanks for your input! – mgcleveland Jan 02 '13 at 17:23
2

While the pthread ID might not be unique, in a implementation where threads map to tasks, the task id (as seen in /proc/PID/task) will in fact be unique system wide, and have a form similar to an actual PID.

Chris Stratton
  • 39,853
  • 6
  • 84
  • 117
  • Although using `gettid()` is probably cleaner than reading a `/proc/...` file. – Alexis Wilke Apr 22 '16 at 23:27
  • @AlexisWilke gettid(2) is a kernel syscall, not a C library function or wrapper. Roundabout means may be necessary to call it - that is why it is often referred to by another name that makes this clear. When I wrote this answer some years ago, I was referring to the id mentioned in /proc to remove *confusion* between this and the very different opaque identifier that is a pthread id, not really proposing how to *obtain* it within code. – Chris Stratton Apr 22 '16 at 23:34
  • In this case you can read the `/proc/self` softlink (see [readlink(2)](http://linux.die.net/man/1/readlink)) because that identifier is the task identifier (the same as what `gettid()` returns.) – Alexis Wilke Apr 23 '16 at 05:43
  • No, that is incorrect. The manual page specifies that /proc/self corresponds to the *process* and that only matches is the ID of the *first* thread. However after Linux 3.17 there exists a /proc/thread-self. – Chris Stratton Apr 23 '16 at 05:50
0

Well, I came across the same problem just now and here is my program for validation.

#include <pthread.h>
#include <stdio.h>

int main() {
    printf("%lu\n", pthread_self());
}

clang -pthread test.c && strace ./a.out

Part of the output is as follows.

...
arch_prctl(ARCH_SET_FS, 0x7f53259be740) = 0
...
write(1, "139995089987392\n", 16139995089987392
)       = 16
...

Then we know 0x7f53259be740 equals to 139995089987392 and the second argument of arch_prctl should be within the process address space(man arch_prctl). That is to say, the thread ID is a virtual address in fact. So if you use pthread_self() to identify threads in a multi-process environment, collisions may happen though it is a small chance.

wizawu
  • 1,881
  • 21
  • 33
  • According to documentation, the `pthread_self()` identifier is unique within one process, but may not be unique between thread of separate processes. – Alexis Wilke Apr 22 '16 at 23:26
0
pthread_equal(id1,id2)

It will compare the ID's of two threads and will return 0 if they are the same and a non zero number if they are different.

Neil
  • 7,227
  • 5
  • 42
  • 43
saim
  • 1
  • 2
  • According to documentation, the `pthread_self()` identifier is unique within one process, but may not be unique between thread of separate processes. – Alexis Wilke Apr 22 '16 at 23:26