Run-time error in pthreads

2

My function main was thus (% with% 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 when you run the code, the order of fnThread has been changed. In pthreads I created an integer vector main and changed the first args 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 already returned well. Can anyone explain why?

    
asked by anonymous 01.10.2017 / 12:01

1 answer

1

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

It's not a good practice to do integer ( casts ) conversions for pointers and vice versa , this may be the motivator for 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 child threads (and vice versa) flexible 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
    
01.10.2017 / 15:13