Different behaviors between Linux and Windows using threads (pthreads)

I am using the linux pthreads library to try out the threads functionality, the code below prints 5 messages on the screen for each thread, each thread waits its turn to display the Controlled message using the traffic lights, in Windows it works perfectly, but in linux the threads do not wait their turn, I have already researched everything that is corner and I could not come to a solution to this problem.

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

typedef struct param{
  int id;
  pthread_mutex_t lock;
  sem_t semaforo;
}valores_t;

void * olamundo(void* args){
  valores_t* p = args;
  sem_post(&p->semaforo);
  for (size_t i = 0; i < 5; i++) {
    printf("Ola mundo da thread %d\n", p->id);
  }
  sem_wait(&p->semaforo);
}

sem_t semaforo;

int main(int argc, char const *argv[]) {
  /* code */

  if(sem_init(&semaforo,0,1)){//valor inicial do semaforo começa por 1
    printf("Erro ao iniciar o semaforo\n");
  }

  valores_t p[2];
  pthread_t threads[2];

    p[0].id = 1;
    p[0].semaforo = semaforo;

    p[1].id = 2;
    p[1].semaforo = semaforo;

  for(int i = 0; i < 2; i++){//inicia as funcoes das threads
    if(pthread_create(&(threads[i]), NULL, &olamundo, &p[i]) == -1){
      printf("Erro ao inicializar a thread\n");
    }
  }

  for(int i = 0; i < 2; i++){
        if(pthread_join(threads[i], NULL)){
      printf("Erro ao sincronizar a thread\n");
    }
    }
    sem_destroy (&semaforo);
  return 0;
}
Author: Victor Stafusa, 2018-03-15

1 answers

It turns out that apparently it is a bug in the compiler, to solve this problem to work on both platforms uses a pointer in struct, to have more details about the solution see this other thread in stackoverflow threads

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

typedef struct param{
    int id;
    pthread_mutex_t lock;
    sem_t *semaforo; //Dagan: change to a pointer to a semaphore
}valores_t;

void * olamundo(void* args){
    valores_t* p = args;
    sem_wait(*(&p->semaforo)); //Dagan: use the semaphore pointer
    for (size_t i = 0; i < 25; i++) {
        printf("Ola mundo da thread %d\n", p->id);
    }
    sem_post(*(&p->semaforo)); //Dagan: use the semaphore pointer
}

sem_t semaforo;

int main(int argc, char const *argv[]) {
    /* code */

    if(sem_init(&semaforo,0,1)){//valor inicial do semaforo começa por 1
        printf("Erro ao iniciar o semaforo\n");
    }

    valores_t p[2];
    pthread_t threads[2];

    p[0].id = 1;
    p[0].semaforo = &semaforo; //Dagan: pass the address of the semaphore

    p[1].id = 2;
    p[1].semaforo = &semaforo; //Dagan: pass the address of the semaphore

    for(int i = 0; i < 2; i++){//inicia as funcoes das threads
        if(pthread_create(&(threads[i]), NULL, &olamundo, &p[i]) == -1){
            printf("Erro ao inicializar a thread\n");
        }
    }

    for(int i = 0; i < 2; i++){
        if(pthread_join(threads[i], NULL)){
            printf("Erro ao sincronizar a thread\n");
        }
    }
    sem_destroy (&semaforo);
    return 0;
}
 -1
Author: Davi Wesley, 2019-05-14 19:45:54