Nicholas Dry
Nicholas Dry

Reputation: 117

Inconsistent values when printing from a thread

I am in the process of learning about thread programming and have been running a test exercise to see how it works when you call a function from pthread_create, however, I am having weird results when doing it. Here is my code:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>

pthread_t *threads;

typedef struct _file {
    int num1;
    int num2;
} file;

void thread_run(void *thing) {
    file *fp = thing;

    printf("num1: %d num2: %d\n", fp->num1, fp->num2);

}

int main(int argc, char **argv) {

    threads = (pthread_t *)malloc(atoi(argv[1]));

    file *args = malloc(sizeof(file));
    args->num1 = 0;
    args->num2 = 0;
    int i;
    for (i = 0; i < atoi(argv[1]); i++) {
        args->num1 = i;
        args->num2 = i + 1;
        pthread_create(&threads[i], NULL, (void *)thread_run, (void *)&args); // the (void *) cast is necessary on my linux distro
    }

    for (i = 0; i < atoi(argv[1]); i++) {
        pthread_join(threads[i], NULL);
    }

    return 0;
}

What I am attempting to have here is when I create the threads in the for loop, I store them all in my *threads pointer.

Then I call the method thread_run with a struct parameter which contains two integer values that I am printing out.

To my knowledge, the expected output of this program when run with ./a.out 3 should be:

num1: 0 num2: 1
num1: 1 num2: 2
num1: 2 num2: 3

However, the output I am getting varies each time but is usually consistent with something like:

num1: 34185264 num2: 0
num1: 34185264 num2: 0
num1: 34185264 num2: 0

I have noticed a few questions with a similar topic but none of the other users seem to be having the issue I have described.

Upvotes: 2

Views: 72

Answers (1)

Code-Apprentice
Code-Apprentice

Reputation: 83527

Every thread has a pointer to the exact same struct. Therefore, they will print the same values. You should malloc() a new struct for each thread inside the for loop.

Also, args is declared as file *args. Note that this is already a pointer, so you should pass it directly rather than its address:

pthread_create(&threads[i], NULL, (void *)thread_run, (void *)args);

Upvotes: 2

Related Questions