Differencebetween Pthread_Self() and Gettid()? Which One Should I Use

difference between the value returned by pthread_self() and gettid()

pthread_self() returns the process-wide unique pthread-id.

gettid() returns the (pthread implementation specific) system-wide unique thread-id (on Linux).


the TID(thread id) returned by gettid() is unique inside a process

Yes.

(or inside a program with multiple processes,

Yes.

inside a process, different thread has different thread id.

Yes.

the TID returned by pthread_self() is unique across processes,

No.

different thread has different TID on the same machine at the same time.

Yes in the same process, No across the whole machine.


As gettid() is Linux specific and therefore not portable, the only way to system widely identify a pthread is to use its (system wide unique) parent process id as returned by getpid() along with its (process-wide unique) pthread-id as returned by pthread_self().

Difference between gettid and pthread_self for Android NDK?

I will just comment on the GetCurrentThread (Win32) part.

It says:

"Retrieves a pseudo handle for the calling thread."

In other words, if you call it from different threads, each thread may receive the same, bogus, handle. Or, in other words, it is possible that the returned value is simply a constant value that is recognized by the Win32 API as a placeholder that represents the current thread.

I'm not sure what needs to be done in order to get a genuine, unique handle for the thread.

I am looking at OpenThread (Win32) function, but I haven't tried it myself.

One thing to remember is that on Windows, "handles" are resources that needs to be cleaned up after use. For each "OpenSomething" function, read the documentation carefully to see if you need to call a "CloseSomething" after use. Also, don't assume that the handle release function to always have the same name as the creation/duplication function. Failure to do so may destabilize the system.

Last but not the least: try search on The Old New Thing.

The thread ID returned by pthread_self() is not the same thing as the kernel thread ID returned by a call to gettid(2)

So, on what basis should I decide whether I should use pthread_self or
gettid to determine which thread is running the function?

You should always use pthread_self() whenever you want to identify a thread within your application. gettid() can be used for certain purposes and if you know it's Linux. For example, gettid() can be used to get seed for a thread specific seed (used in srand()).

Both are non portable.

This is not entirely true. gettid() is not portable as its a Linux specific function. But pthread_self() is portable as long as you don't make any assumptions about its representation.

For example, the following is not portable.

printf("Thread ID is: %ld", (long) pthread_self());

as there's no guarantee that whatever pthread_self() is going to be an integer of some sort. But

pthread_t my_tid; //filled elsewhere

pthread_t tid = pthread_self();

if( pthread_equal(my_tid, tid) ) {
/* do stuff */
}

is fully portable.

The former is not portable because it assumes that thread id is an integer whereas the latter is not.

Why are there two different functions to get the thread ID?

They are not two different ways to get the same value. One (pthread_self() is provided by the thread library (pthreads) while the other (gettid()is an OS-specific function. A different OS may provide a different interface/syscall to get thread ID similar to gettid(). So you can't rely on gettid() in a portable application.

C - pthread_self() getting truncated first 4 bytes?

this function body is the root of the problem:

size_t i;
for (i = sizeof(i); i; --i)
{
fprintf(stderr, "%02x", *(((unsigned char*) &id) + i - 1));
}

the pthread_t does not have the same size as an 'size_t' and the code is using sizeof(i) to print the bytes of a pthread_t. suggest:

for (i = sizeof(pthread_t); i; --i)
{
fprintf(stderr, "%02x", *(((unsigned char*) &id) + i - 1));
}

although a better method, not using a loop, would be:

fprintf( stderr, "%*x", (int)(2*sizeof(pthread_t)), (int)id );

caveat: the following code does not compile cleanly. It outputs a warning message about the unused parameter abc

So, with a 'improved' function: printThreadID() the program that produced the output is:

#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <netdb.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <pthread.h>
#include <errno.h>

#define FROM_CREATE (0)
#define FROM_THREAD (1)

#define QUEUE_SIZE (10)
pthread_t *threads_array;
int abc;

void server_loop( void );
void *a_loop(void *abc);
void printThreadID( int, pthread_t );

int main( void )
{
server_loop();
return 0;
}

void server_loop()
{
pthread_t thread_id;
if( NULL == (threads_array = malloc(QUEUE_SIZE * sizeof(pthread_t)) ))
{
perror( "malloc for thread array failed" );
exit( EXIT_FAILURE );
}

// implied else, malloc successful

for (int i = 0; i < QUEUE_SIZE; i++)
{
if (pthread_create(&thread_id, NULL, a_loop, (void*)&abc) < 0)
{
perror("Thread creation failed");
fprintf(stderr, "Thread creation #%d failed\n", i);
printThreadID(FROM_CREATE, thread_id);
exit( EXIT_FAILURE );
}

// implied else, pthread_create successful

//... store threadID in array
//fprintf(stderr, "Thread created: ");
printThreadID(FROM_CREATE, thread_id);

threads_array[i] = thread_id;

}
sleep(5);
}

void *a_loop(void *abc)
{
//fprintf(stderr, "@@@@ ");
printThreadID( FROM_THREAD, pthread_self());

//... find index of matching pthread_equal(pthread_self(), array[i])

while (1)
{
}
return 0;
}

// HELPER METHOD
void printThreadID(int fromThread, pthread_t id)
{
//size_t i;

//for (i = sizeof(i); i; --i)
//{
// fprintf(stderr, "%02x", *(((unsigned char*) &id) + i - 1));
//}
if( FROM_THREAD == fromThread )
{
fprintf( stderr, "@@@@ %ld\n", (long int)id );
}
else
{
fprintf( stderr, "thread created: %ld\n", (long int)id );
}
//fprintf(stderr, "\n");
}

Here is the output of a typical run of the program, note the exact order of the outputs is depending on which thread wins the race.

thread created: 140506339571456
@@@@ 140506339571456
thread created: 140506331178752
thread created: 140506322786048
thread created: 140506314393344
thread created: 140506306000640
thread created: 140506297607936
thread created: 140506289215232
thread created: 140506280822528
thread created: 140506272429824
thread created: 140506264037120
@@@@ 140506331178752
@@@@ 140506297607936
@@@@ 140506322786048
@@@@ 140506289215232
@@@@ 140506280822528
@@@@ 140506314393344
@@@@ 140506272429824
@@@@ 140506264037120
@@@@ 140506306000640

How do I get a thread ID from an arbitrary pthread_t?

Since pthreads do not need to be implemented with Linux threads (or kernel threads at all, for that matter), and some implementations are entirely user-level or mixed, the pthreads interface does not provide functions to access these implementation details, as those would not be portable (even across pthreads implementations on Linux). Thread libraries that use those could provide this as an extension, but there do not seem to be any that do.

Other than accessing internal data structures of the threading library (which you understandably do not want, although with your assumptions about processor affinity and Linux thread IDs, your code will not be portable anyway), you may be able to play a trick at creation time, if you control the code that creates the threads:

Give pthread_create() an entry function that calls gettid() (which by the way you are likely to have to do using the syscall macro directly because it is not always exported by libc), stores the result somewhere, and then calls the original entry function. If you have multiple threads with the same entry function, you can pass an incremented pointer into an array in the arg argument to pthread_create, which will then be passed to the entry function you created to store the thread ID in. Store the pthread_t return value of pthread_create in the same order, and then you will be able to look up the Linux thread IDs of all threads you created given their pthread_t value.

Whether this trick is worth it, depends on how important setting the CPU affinity is in your case, versus not accessing internal structures of the thread library or depending on a thread library that provides pthread_setaffinity_np.

call pthread_self() from a single-threaded application

pthread_self is defined to return the calling thread's ID regardless of whether the program
is multi-threaded or a single-threaded.

As you found, the return value of pthread_self() isn't same as the LWP in Linux (gettid) and as such it doesn't have any meaning outside of the process; pthread_t is
an opaque type. Related: The thread ID returned by pthread_self() is not the same thing as the kernel thread ID returned by a call to gettid(2)

Its utility is very limited as there's not much practical use for pthread_t in a single-threaded program. You can use in pthread_setschedparam for example.

But if you are asking whether returns any valid value in single-threaded program, then the answer is yes.

How to get thread id of a pthread in linux c program?

pthread_self() function will give the thread id of current thread.

pthread_t pthread_self(void);

The pthread_self() function returns the Pthread handle of the calling thread. The pthread_self() function does NOT return the integral thread of the calling thread. You must use pthread_getthreadid_np() to return an integral identifier for the thread.

NOTE:

pthread_id_np_t   tid;
tid = pthread_getthreadid_np();

is significantly faster than these calls, but provides the same behavior.

pthread_id_np_t   tid;
pthread_t self;
self = pthread_self();
pthread_getunique_np(&self, &tid);


Related Topics



Leave a reply



Submit