Pregunta

I want to do something like this:

void *do_work_son(void *data)
{            
    mystruct *d = (mystruct*)data;
    while(true)
    {
        // d->whatever is corrupt
    }
}

void start_thread(pthread_t *mt)
{
    mystruct data = ...;
    pthread_create(&(*mt), NULL, do_work_son, (void *)&data);
}

int main()
{
    pthread mt;
    start_thread(&mt);
    // do more stuff here
    pthread_join(mt, NULL);
}

The idea is spawn off some threads and keep doing more work in main... then when done doing more work, wait for the threads to finish.

It compiles fine, but the data struct is corrupted when it gets accessed inside do_work_son. I think this is because the threads are exiting, even though I'm calling join in main. If I move the pthread_{create,join} calls both to start_thread, it works fine, but then my main function is blocked by the while loop. Am I crazy for doing it this way?

¿Fue útil?

Solución 2

The answer is simple: you are passing a reference of a local variable and then leaving the scope. Replace it with data allocated on heap and it would work like a charm

void start_thread(pthread_t *mt)
{
    mystruct *data = malloc(sizeof(*data));
    ...;
    pthread_create(mt, NULL, do_work_son, data);
}

EDIT:

About preassignment question:

void start_thread(pthread_t *mt)
{
    mystruct local_data = {...};
    mystruct *data = malloc(sizeof(*data));
    *data = local_data;
    ...;
    pthread_create(mt, NULL, do_work_son, data);
}

Otros consejos

I think this is because the threads are exiting,

No, that's because data is an automatic variable in the start_thread() function, which is invalidated when start_thread() returns, so using its address afterwards invokes undefined behavior.

Either malloc()ate some memory for it, or make it static, or whatever. Just make sure it survives the death of start_thread().

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top