This is what I am wondering:
If I create a thread with pthread_create() and then call pthread_self() from that thread, will that value match the pthread_t value that I pass to pthread_create in the main thread?
//pthread_t variable
pthread_t producer_thread = (pthread_t*)malloc(sizeof(pthread_t));;
//create the thread
pthread_create(producer_thread, NULL, producer, NULL);
printf("Pthread_t variable after creating thread says %d\n", producer_thread);
....
//function passed to thread
void producer(void *p){
printf("Pthread self says: %d\n", pthread_self());
}
Return type of pthread_self is pthread_t which is basically a pointer not of integer type.
So, it is printing its address(typecasted to int), not pthread_t structure.
You can use pthread_equal function to check if these pthread_t are same or not. Means, in another thread, use
printf("%d\n", pthread_equal(mythreadId, pthread_self()));
It should print a non-zero number indicating that they correspond to the same thread.
If they are not same, then it is a problem.
Print mythreadId in the thread what is spawns. It must match with main's pthread_t. If they are different, then there is a problem.
Related
When creating an pthread, pthread_create() is used. First parameter of this function is thread_id.
I tried to access this value pthread_self() but this gives something very big and not the numbers I gave while creating.
Is there a way to access this value?
for(int i = 0; i < necessaryThreadCount; i++){
pthread_create(&threadIDs[i], NULL, theFunction, (void*)&requiredStructre[i]);
}
my question is, how can i access the value of given threadID inside theFunction?
Solution:
I just added another variable to the struct I pass as parameter.
First parameter is pointer to thread_id which you need to declare first.
ID will get assigned after you create thread using pthread_create(). refer the below:
int main()
{
pthread_t thread; // declare thread
pthread_create(&thread, NULL, func, NULL);
printf("the thread id = %d\n", thread);
}
thread_id is for the new thread that is created. if you execute pthread_self() in the current thread it returns a different value from the newly created thread.
Hope the below example may help you to understand thread id creation:
[NOTE: not a good idea to have global pthread_t declared]
Example:
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
pthread_t ctid;
void* thread_function(void* arg)
{
printf("Inside the thread\n");
printf("ctid: %ld, self: %ld", ctid, pthread_self());
// exit the current thread
pthread_exit(NULL);
}
void createthread()
{
pthread_create(&ctid, NULL, &thread_function, NULL);
printf("This line may be printed"
" before thread terminates\n");
// Waiting for the created thread to terminate
pthread_join(ctid, NULL);
pthread_exit(NULL);
}
// Driver code
int main()
{
createthread();
return 0;
}
I'm trying to implement pthread_self() in C but I'm confused on what exactly it does. I'm aware that it returns the thread ID but is that ID a memory location because it returns a pthread_t which I'm not sure how to interpret. Additionally, how would I go about retrieving the id of the thread, do I just create a new thread and return it?
pthread_self() returns the ID of the thread. Please check man pages for pthread_self and pthread_create.
man 3 pthread_self
man 3 pthread_create
For pthread_create(), the first argument is of type pthread_t. It is assigned the ID of the newly created thread. This ID is used to identify the thread for other pthread functions. The abstract type of pthread_t is implementation dependent.
Before returning, a successful call to pthread_create() stores the ID of the new thread in the buffer pointed to by thread; this identifier is used to refer to the thread in subsequent calls to other pthread functions.
pthread_self returns the same ID, what pthread_create stores in the first argument "thread"
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine) (void *), void *arg);
pthread_t pthread_self(void);
In my system pthread_t type is "unsigned long int"
/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h:typedef unsigned long int pthread_t;
In the following example, the value returned by pthread_self() and th1 are same.
// main function:
pthread_t th1;
if(rc1 = pthread_create(&th1, NULL, &functionC1, NULL))
{
printf("Thread creation failed, return code %d, errno %d", rc1, errno);
}
printf("Printing thread id %lu\n", th1);
// Thread function:
void *functionC1(void *)
{
printf("In thread function Printing thread id %lu\n", pthread_self());
}
Output:
Printing thread id 140429554910976
In thread function Printing thread id 140429554910976
Please check blog Tech Easy for more information on threads.
The signature of pthread_create(3) is:
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine) (void *), void *arg);
What are the requirements on the storage duration of the pthread_t *thread argument? The man page for pthread_create says:
Before returning, a successful call to pthread_create() stores the ID of the new thread in the buffer pointed to by thread;
But it's not clear if it means that it stores the value there so that the caller can examine it, or if it uses that buffer to store the value (implying that the buffer needs to stay usable for the whole lifetime of the child thread).
Similarly, pthread_self says it returns
the same value that is returned in *thread in the pthread_create(3) call that created this thread.
but it's not clear if it means that it returns the value stored in *thread or a value equal to what was returned in *thread.
Concretely, I'm wondering if it's legal to have something like:
void make_thread(void) {
pthread_t tid;
return pthread_create(&tid, NULL, some_fn, NULL);
}
or if tid needs to be malloc'd. When I put tid on the stack, I get a bunch of errors in valgrind related to _Unwind_ForcedUnwind, which makes me suspect that *thread needs to remain valid for the lifetime of the child thread.
The thread ID is returned for your own use. You don't need to store it if you're going to detach the thread or the thread is going to detach itself.
void make_thread(void) {
pthread_t tid;
return pthread_create(&tid, NULL, some_fn, NULL);
}
This is kind of odd. You can't join the thread, because you didn't keep its ID. And you didn't detach it. I suppose this could be fine if the thread detaches itself, but that's an odd way to do things.
My command line tool keeps throwing the bus error: 10 message. Xcode debugger shows EXC_BAD_ACCESS message and highlights the function call that creates the thread. Manual debugging shows that the execution flow breaks at random positions inside the thread flow. I tried another compiler (gcc), but it ended up the same. Disabling pthread_mutex_lock() and pthread_mutex_unlock() doesn't help. I wrote this small example that reproduces the error.
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
typedef struct thread_args {
pthread_mutex_t* mutex;
} thread_args;
void* test(void* t_args) {
printf("Thread initiated\n");
thread_args* args = (thread_args* )t_args;
printf("Args casted\n");
pthread_mutex_lock(args->mutex);
printf("Mutex locked\n");
pthread_mutex_unlock(args->mutex);
printf("Mutex unlocked\n");
pthread_exit(NULL);
}
int main() {
pthread_mutex_t mutex1;
pthread_mutex_init(&mutex1, NULL);
thread_args args;
args.mutex = &mutex1;
pthread_t* thread;
printf("Initiating a thread\n");
pthread_create(thread, NULL, test, &args);
return(0);
}
I think, in your case,
pthread_create(thread, NULL, test, &args);
at this call, thread is a pointer and not allocated memory. So, essentially pthread_create() tries to write into uninitialized memory, which creates undefined behavior.
Referring the man page of pthread_create()
Before returning, a successful call to pthread_create() stores the ID of the new thread in the buffer pointed to by thread;....
Instead, you can do
pthread_t thread;
...
pthread_create(&thread, NULL, test, &args);
You're using an uninitialized pointer to your pthread_t. The actual storage of the pthread_t needs to be somewhere!
Try :
int main() {
pthread_mutex_t mutex1;
pthread_mutex_init(&mutex1, NULL);
thread_args args;
args.mutex = &mutex1;
pthread_t thread;
printf("Initiating a thread\n");
pthread_create(&thread, NULL, test, &args);
return(0);
}
As other answers pointed out, you need to initialize your pointer thread which you can simply do with:
pthread_t thread;
pthread_create(&thread, NULL, test, &args);
Well, then I'll have to allocate memory dynamically, because different
threads are spawned inside many different functions, hence I can't use
local variables, because I'm not going to join the threads. Then, how
can I free the allocated memory without waiting for the thread to
finish, i.e. without calling join?
No. You don't need to dynamically allocate just because you are going to spawn multiple threads. The thread identifier is no longer needed once a thread has been created So whether it's a local variable or malloced is not important. It's only needed when you need to join or change some characteristics of the thread -- for which you need the ID. Otherwise, you can even reuse the same thread for creating multiple threads. For example,
pthread_t thread;
for( i = 0; i<8; i++)
pthread_create(&thread, NULL, thread_func, NULL);
is perfectly fine. A thread can always get its own ID by calling pthread_self() if needed. But you can't pass a local variable mutex1 to thread functions as once main thread exits, the mutex1 no longer exits as thread created continues to use it. So you either need malloc mutex1 or make it a global variable.
Another thing to do is that if you decide to let the main thread exit then you should call pthread_exit(). Otherwise, when the main thread exits (either by calling exit or simply return) then the whole process will die, meaning, all the threads will die too.
I've been reading and learning about POSIX threads, and tried to write some simple codes to understand it better.
#include <stdio.h> /* standard I/O routines */
#include <pthread.h> /* pthread functions and data structures */
/* function to be executed by the new thread */
void* PrintHello(void* data)
{
pthread_t tid = (pthread_t)data;
printf("Hello from new thread %d - got %d\n", pthread_self(), tid);
pthread_exit(NULL); /* terminate the thread */
}
int main(int argc, char* argv[])
{
int rc; /* return value */
pthread_t thread_id;
int tid;
thread_id = pthread_self();
printf("FLAG = %d ", thread_id);
/* create a new thread that will execute 'PrintHello' */
rc = pthread_create(&thread_id, NULL, PrintHello, (void*)thread_id);
if(rc) /* could not create thread */
{
printf("\n ERROR: return code from pthread_create is %u \n", rc);
exit(1);
}
printf("\n Created new thread (%d) ... \n", thread_id);
pthread_exit(NULL); /* terminate the thread */
}
For this code I get the following output:
FLAG = 363480832
Created new thread (355198720) ...
Hello from new thread 355198720 - got 363480832
What is bothering me is why thread_id which is 363480832, becomes 355198720, same as thread_id of a function that was called from main (PrintHello()). I assumed that thread id doesn't change throughout the program execution. Or is it something inside the function that changes it?
If you're doing anything with a pthread_t other than passing it to a function that takes one, you're doing something wrong. Only the pthreads API knows how to use a pthread_t correctly. They can have any internal structure that's convenient for the implementation.
Being a C language construct, pthread_t behaves more like char *. The necessary language constructs to make it behave like std::string don't exist. So you have to treat it like char *.
A char * contains a string somehow, but you have to understand its implementation to get that value out. Consider:
char *j = "hello";
char *k = strdup (j);
if (j == k)
printf ("This won't happen\n");
printf ("%d\n", j);
printf ("%d\n", k); // these won't be equal
You can't compare char *'s with == to see if they refer to the same string. And if you print out j and k, you'll get different values.
Similarly, a pthread_t refers to one particular thread somehow. But you have to understand how to get the value out. Two pthread_ts can have different apparent values but still refer to the same thread just as two char *s can have different apparent values but still refer to the same string.
Just as you compare two char *'s with strcmp if you want to tell if they refer to the same string value, you compare two pthread_ts with pthread_equal to tell if they refer to the same thread.
So this line of code makes no sense:
printf("FLAG = %d ", thread_id);
A pthread_t is not an integer and you can't print it with a %d format specifier. POSIX has no printable thread IDs. If you want one, you need to code one (perhaps using pthread_getspecific).
In C, arguments are passed by value. In particular, the argument (void *)thread_id is an expression that's evaluated before calling pthread_create, so the fact that pthread_create writes to thread_id as a result of &thread_id being passed as the first argument is irrelevant. If you were instead passing &thread_id rather than (void *)thread_id as the argument to the new thread start function, and dereferencing it there, then you may see the effects you want; however, it's not clear to me that pthread_create's writing of the new thread id via its first argument is required to take place before the new thread starts, so there is probably a data race if you do it that way.
Further, note that David's answer is also correct. It's invalid to print thread ids this way since they are formally an opaque type.
In this line:
rc = pthread_create(&thread_id, NULL, PrintHello, (void*)thread_id);
as the manual says, pthread_create() shall store the ID of the created thread in the location referenced by thread_id. In this example, it would be modified to 355198720, which is the tid of new thread PrintHello().
Besides, it may be better to change the argument for PrintHello to:
rc = pthread_create(&thread_id, NULL, PrintHello, (void*)&thread_id);
and in PrintHello(), it would be:
void* PrintHello(void* data)
{
pthread_t tid = (pthread_t)(*data);
...
}