Pergunta

I want to create multiple threads (10 in the example below) and have each of them run a function.

Here is my code:

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

typedef struct arg_struct {
    int id;
    int val;
} arg_struct;

void *printarg(void *params) {
    arg_struct *args = (arg_struct *) params;
    printf("id %i value %i\n", args->id, args->val);
    return 0;
}

int main() {
    int i = 0;
    pthread_t threads[10];
    for (i = 0; i < 10; i++) {
        arg_struct arg;
        arg.id = i;
        arg.val = i + 10;
        pthread_create(&(threads[i]), NULL, &printarg, &arg);
    }
    for (i = 0; i < 10; i++) {
        pthread_join(threads[i], NULL);
    }
    return 0;
}

I was expecting an output like this during execution:

id 0 value 10
id 1 value 11
id 2 value 12
id 3 value 13
id 4 value 14
id 5 value 15
id 6 value 16
id 7 value 17
id 8 value 18
id 9 value 19

But instead I get outputs like this:

id 2 value 12
id 3 value 13
id 3 value 13
id 4 value 14
id 6 value 16
id 6 value 16
id 9 value 19
id 9 value 19
id 9 value 19
id 9 value 19

Every time I rerun my program the output changes slightly. The id's & value's repeat and the pattern seems irregular.

What is happening? Are the repeats happening because the child threads are also creating threads in the for loop? If so, I am confused because in many of the examples of pthread_create I read, people seemed to be using a loop which iterates N times to create N threads (exactly like above). Therefore I assumed that the above code will have 1 master thread create N child threads? Am I wrong? Thanks in advance.

Foi útil?

Solução

Each thread is being passed a pointer to the arg_struct that is declared inside the loop, which is created anew on each iteration. If none of the threads execute until you exit the loop, they are technically referencing a variable that has gone out of scope. Even if it hadn't gone out of scope (say you declared it at the top of main), they would all see the final value that you placed there. From your trace, it appears that the threads are starting in random clumps relative to the loop.

You will need to allocate a separate arg_struct for each thread, and make sure that each one remains valid for the lifetime of the thread.

Try this:

#define NUM_THREADS 10

int main() {
    int i = 0;
    pthread_t threads[NUM_THREADS];
    arg_struct args[NUM_THREADS];
    for (i = 0; i < NUM_THREADS; i++) {
        args[i].id = i;
        args[i].val = i + 10;
        pthread_create(&threads[i], NULL, &printarg, &args[i]);
    }
    for (i = 0; i < NUM_THREADS; i++) {
        pthread_join(threads[i], NULL);
    }
    return 0;
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top