pthread_exit() and pthread_join() don't work

158 Views Asked by At

I don't know why it doesn't return the value that I type in. I know it's not the void* arg because it prints the right number, but I don't have any idea.

CODE:

#include <unistd.h>
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <sys/types.h>


void* stampa(void* arg) {
    float dato = *(float*)arg;
    printf("Read: %f\n", dato);
    
    pthread_exit((void*)&dato);
}

// Main
int main() {
    system("clear");

    pthread_t miot;
    int creathread;
    float x;
    float *status;

    printf("Number: ");
    scanf("%f", &x);

    creathread = pthread_create(&miot, NULL, stampa, (void*)&x);

    if (creathread != 0) {
        printf("Error\n");
    }

    pthread_join(miot, (void*)&status);
    printf("Returned: %f\n", *status);

    return 0;
}

RESULT:

Number: 10
Read: 10.000000
Returned: 0.000000
1

There are 1 best solutions below

1
On
void* stampa(void* arg) {
    float dato = *(float*)arg;
    printf("Read: %f\n", dato);
    
    pthread_exit((void*)&dato);
}

dato no longer exists as soon as the function returns. By taking the address of that variable and dereferencing it after the function returns (back in the main thread), you're invoking undefined behavior.

You can either:

  • Cast the float to void * and return the value directly (as if it were a pointer) and cast it back to float in main.
    • This may break some rules (is a void * guaranteed to be big enough to hold a float?), but I've seen this used often.
  • Allocate an object using malloc and return that pointer.

First option:

void* stampa(void* arg) {
    float dato = *(float*)arg;
    printf("Read: %f\n", dato);
    
    pthread_exit((void*)dato);
}

// Main
int main() {
    system("clear");

    pthread_t miot;
    int creathread;
    float x;
    float status;

    printf("Number: ");
    scanf("%f", &x);

    creathread = pthread_create(&miot, NULL, stampa, (void*)&x);

    if (creathread != 0) {
        printf("Error\n");
    }

    pthread_join(miot, (void*)&status);
    printf("Returned: %f\n", status);

    return 0;
}