Pthreads and Structures C++

I am using structures in C++, and i try to save pointers in that structures, but when i try to use that structure in a thread i cant get the data of the structure.

struct threadData {
   void* memPointer;
   void* instructionPointer;
   void* stackPointer;
   int memsize;
};

void *worker_thread(void *arg) {
    struct threadData *my_data;
    my_data = (struct threadData *) arg;
    cout<<"INSTRUCTION POINTER: "<<my_data->instructionPointer<<endl;
    cout<<"MEMORY POINTER: "<<my_data->memPointer<<endl;
    cout<<"STACK POINTER: "<<my_data->stackPointer<<endl;
    cout<<"MEMORY SIZE: "<<my_data->memsize<<endl;

 }

 int main() {
    pthread_t my_thread;
    int ret;
    struct threadData td = { calloc(1, 32), calloc(1000000, 64),     calloc(34, 4),6475 };
    ret = pthread_create(&my_thread, NULL, worker_thread, (void *) &td);
    pthread_detach(my_thread);
    //pthread_exit(NULL);
 }

But when i use pthread_exit(NULL) after pthread_detach i can use the information of the structure in the method "worker_thread".

Upvotes: 2

Views: 200

Answers (2)

Vaughn Cato
Vaughn Cato

Reputation: 64308

Without pthread_exit, you are returning from main, and the local variable td is destroyed before the other threads are completed.

By calling pthread_exit, you force the main thread to wait for the other threads to complete, so td doesn't get destroyed too early.

As @Aconcagua noticed, the documentation for pthread_exit says that the calling thread is terminated. It doesn't make an exception for the main thread, so at least in principle, the main thread's stack could disappear while the other threads were still executing. This means that even with the call to pthread_exit, you have undefined behavior.

Upvotes: 2

DaoWen
DaoWen

Reputation: 33019

Since td is allocated on the stack in main, it gets clobbered by some clean-up code that the runtime executes after you return from main. Allocate your td struct on the heap instead of on the stack, and it will work as expected:

struct threadData tdVal = { calloc(1, 32), calloc(1000000, 64),     calloc(34, 4),6475 };
struct threadData *td = malloc(sizeof(*td));
*td = tdVal;
// ...
ret = pthread_create(&my_thread, NULL, worker_thread, (void *) td);

However, you still have a problem. Returning from main will kill the other pthreads in your program. Since there's no synchronization in your code preventing main from completing before worker_thread is run, you can't even guarantee that worker_thread will run at all.

You should probably not detach the worker thread, and instead use pthread_join to make sure it has completed before returning from main. Also note that if you ensure main does not return before worker_thread completes, then there's no problem with leaving td on the stack.

Upvotes: 3

Related Questions