Naming a pthread using meaningful names, can be a very useful feature for debugging multi-threaded applications as it can make your logs very informative.
For this reason, we are presenting two examples demonstrating the use of names in pthreads
.
- [download id=”3786″]
- [download id=”3788″]
Example 1: The pthread decides for its name
The following code, creates a pthread
which later, it will give itself a meaningful name.
[download id=”3786″]
// #define _GNU_SOURCE is needed for the resolution of the following warnings //warning: implicit declaration of function ‘pthread_setname_np’ [-Wimplicit-function-declaration] //warning: implicit declaration of function ‘pthread_getname_np’ [-Wimplicit-function-declaration] #define _GNU_SOURCE #include <stdio.h> #include <sys/types.h> #include <pthread.h> #include <asm/errno.h> #include <errno.h> // #include <stdlib.h> is needed for the resolution of EXIT_SUCCESS #include <stdlib.h> //The thread name is a meaningful C language string, whose length is restricted to 16 characters, including the terminating null byte. #define MAX_LENGTH_PTHREAD_NAME (16) struct thread_info_t { // Used to identify a thread. pthread_t thread_id; }; // This is the thread that will be called by pthread_create() and it will be executed by the new thread. void *self_named_thread(void *data) { // We know that the input data pointer is pointing to a thread_info_t so we are casting it to the right type. struct thread_info_t *thread_info = (struct thread_info_t *) data; const int setname_rv = pthread_setname_np(thread_info->thread_id, "Tom Hanks"); if (setname_rv) { errno = setname_rv; perror("Could not set pthread name"); } char thread_name[MAX_LENGTH_PTHREAD_NAME]; const int getname_rv = pthread_getname_np(thread_info->thread_id, thread_name, MAX_LENGTH_PTHREAD_NAME); if (getname_rv) { errno = getname_rv; perror("Could not get pthread name"); } //This function always succeeds, returning the calling thread's ID. const pthread_t tid = pthread_self(); //Usually pthread_t is defined as follows: //typedef unsigned long int pthread_t; //so we print pthread_t as an unsigned long int fprintf(stdout, "I am thread with ID '%lu', my name is '%s' and I gave me my name by myself\n", tid, thread_name ); return NULL; } int main() { struct thread_info_t thread_info; const int create_rv = pthread_create(&(thread_info.thread_id), NULL, &self_named_thread, (void *) &thread_info); if (create_rv) { errno = create_rv; perror("Could not create thread"); return EXIT_FAILURE; } // The pthread_join() function suspends execution of the calling thread until the target thread terminates, unless the target thread has already terminated. const int join_rv = pthread_join(thread_info.thread_id, NULL); if (join_rv) { errno = create_rv; perror("Could not join thread"); } return EXIT_SUCCESS; }
[download id=”3786″]
Example 2: The parent decides for the pthread name
The next code, creates a pthread
and the parent gives the thread a meaningful name.
[download id=”3788″]
// #define _GNU_SOURCE is needed for the resolution of the following warnings //warning: implicit declaration of function ‘pthread_setname_np’ [-Wimplicit-function-declaration] //warning: implicit declaration of function ‘pthread_getname_np’ [-Wimplicit-function-declaration] #define _GNU_SOURCE #include <stdio.h> #include <sys/types.h> #include <pthread.h> #include <asm/errno.h> #include <errno.h> // #include <stdlib.h> is needed for the resolution of EXIT_SUCCESS #include <stdlib.h> // #include <unistd.h> is needed for the resolution of unsigned int sleep(unsigned int seconds); #include <unistd.h> //The thread name is a meaningful C language string, whose length is restricted to 16 characters, including the terminating null byte. #define MAX_LENGTH_PTHREAD_NAME (16) struct thread_info_t { // Used to identify a thread. pthread_t thread_id; }; // This is the thread that will be called by pthread_create() and it will be executed by the new thread. void *self_named_thread(void *data) { // We know that the input data pointer is pointing to a thread_info_t so we are casting it to the right type. struct thread_info_t *thread_info = (struct thread_info_t *) data; //Added an artificial delay for the sake of the example. //Making sure the parent thread gave the pthread a name. sleep(1); char thread_name[MAX_LENGTH_PTHREAD_NAME]; const int getname_rv = pthread_getname_np(thread_info->thread_id, thread_name, MAX_LENGTH_PTHREAD_NAME); if (getname_rv) { errno = getname_rv; perror("Could not get pthread name"); } //This function always succeeds, returning the calling thread's ID. const pthread_t tid = pthread_self(); //Usually pthread_t is defined as follows: //typedef unsigned long int pthread_t; //so we print pthread_t as an unsigned long int fprintf(stdout, "I am thread with ID '%lu', my name is '%s' and my parent gave me my name\n", tid, thread_name ); return NULL; } int main() { struct thread_info_t thread_info; const int create_rv = pthread_create(&(thread_info.thread_id), NULL, &self_named_thread, (void *) &thread_info); if (create_rv) { errno = create_rv; perror("Could not create thread"); return EXIT_FAILURE; } const int setname_rv = pthread_setname_np(thread_info.thread_id, "Bob Marley"); if (setname_rv) { errno = setname_rv; perror("Could not set pthread name"); } // The pthread_join() function suspends execution of the calling thread until the target thread terminates, unless the target thread has already terminated. const int join_rv = pthread_join(thread_info.thread_id, NULL); if (join_rv) { errno = create_rv; perror("Could not join thread"); } return EXIT_SUCCESS; }
[download id=”3788″]
This post is also available in: Greek