Error in running order of pthreads

Asked

Viewed 256 times

2

My job main was like this (fnThread was set further back):

int main() {

  int i;
  int *result;

  pthread_t tid[N];

  for (i=0; i<N; i++) {
    if (pthread_create (&tid[i], 0 ,fnThread, (void*)(&i)) != 0){ 
      printf("Erro ao criar tarefa.\n");
      return 1;
    }
    printf("Lancou uma tarefa\n");
  }


  for (i=0; i<N; i++) {
    if (pthread_join (tid[i], (void**)(&result)) != 0) {
      printf("Erro ao esperar por tarefa.\n");
      return 2;
    }
    printf("Tarefa retornou com resultado = %d\n", *result);
  }
return 0;
}

But running the code, the order of pthreads was changed. In main I created an integer vector args and changed the first for to the following:

for (i=0; i<N; i++) {
    args[i] = i;
    if (pthread_create (&tid[i], 0 ,fnThread, (void*)(&args[i])) != 0){ 
        printf("Erro ao criar tarefa.\n");
        return 1;
    }
    printf("Lancou uma tarefa\n");
}

... and has returned well. Someone can explain to me why?

1 answer

1

You are right: A ordem de criação and the ordem de execução threads are not the same! And this is not a mistake, but the natural behavior of pthreads.

It’s not good practice to keep making conversions (casts) of integer values for pointers and vice versa, this may be the motivator of the error you mentioned in your question.

Here is an example (tested) demonstrating how to use a technique in which a context is created for each thread and its pointer passed from the main thread to the daughter threads (and vice versa) very flexibly and without dangerous conversions:

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

#define N  (10)

typedef struct thread_context_s {
    pthread_t tid;
    int id;
    int status;
} thread_context_t;


void * fnThread(void* arg){
    thread_context_t * ctxt = (thread_context_t*) arg;
    printf("Executando tarefa id: %d\n", ctxt->id );
    ctxt->status = ctxt->id;
    return ctxt;
}

int main(void) {
    int i = 0;
    thread_context_t ctxt[N];

    for( i = 0; i < N; i++ ) {
        ctxt[i].id = i;
        if(pthread_create( &ctxt[i].tid, 0, fnThread, (void*) &ctxt[i] )) {
            printf("Erro ao criar tarefa id: %d\n", i );
            return 1;
        }
        printf("Lancou tarefa id: %d\n", i );
    }

    for( i = 0; i < N; i++ ) {
        if(pthread_join( ctxt[i].tid, NULL )) {
            printf("Erro ao esperar por tarefa id: %d\n", ctxt[i].id );
            return 2;
        }
        printf("Tarefa id: %d retornou: %d\n", ctxt[i].id, ctxt[i].status );
    }

    return 0;
}

Compiling:

$ gcc -Wall -Wextra -pthread thread.c -o threads

Testing:

./threads 
Lancou tarefa id: 0
Lancou tarefa id: 1
Lancou tarefa id: 2
Lancou tarefa id: 3
Executando tarefa id: 0
Lancou tarefa id: 4
Lancou tarefa id: 5
Executando tarefa id: 2
Lancou tarefa id: 6
Executando tarefa id: 3
Lancou tarefa id: 7
Executando tarefa id: 1
Lancou tarefa id: 8
Executando tarefa id: 4
Executando tarefa id: 7
Lancou tarefa id: 9
Tarefa id: 0 retornou: 0
Tarefa id: 1 retornou: 1
Executando tarefa id: 8
Tarefa id: 2 retornou: 2
Tarefa id: 3 retornou: 3
Executando tarefa id: 9
Executando tarefa id: 6
Tarefa id: 4 retornou: 4
Executando tarefa id: 5
Tarefa id: 5 retornou: 5
Tarefa id: 6 retornou: 6
Tarefa id: 7 retornou: 7
Tarefa id: 8 retornou: 8
Tarefa id: 9 retornou: 9

Browser other questions tagged

You are not signed in. Login or sign up in order to post.