代码之家  ›  专栏  ›  技术社区  ›  Davi Wesley

对线程使用参数

  •  0
  • Davi Wesley  · 技术社区  · 6 年前

    我正在使用linux pthreads库来尝试线程功能,下面的代码在屏幕上为每个线程打印5条消息,每个线程等待轮到它来显示使用信号量控制的消息,在Windows中,它工作得很好,但在linux中,线程不等待轮到它,我已经研究了所有正在唱歌的内容,我无法找到解决这个问题的方法。我的推论是,我对参数结构做了一些错误的操作

    #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_wait(&p->semaforo);
      for (size_t i = 0; i < 5; i++) {
        printf("Hello from thread %d\n", p->id);
      }
      sem_post(&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("Error\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++){
        if(pthread_create(&(threads[i]), NULL, &olamundo, &p[i]) == -1){
          printf("Error\n");
        }
      }
    
      for(int i = 0; i < 2; i++){
            if(pthread_join(threads[i], NULL)){
          printf("Error\n");
        }
        }
        sem_destroy (&semaforo);
      return 0;
    }
    
    1 回复  |  直到 6 年前
        1
  •  1
  •   Omer Dagan    6 年前

    我已经在ubuntu 14.04(gcc v4.8)上测试了您的代码,它的工作原理与预期相符,因此我认为这是编译器的问题。作为评论人 詹姆斯·拉格 建议您的编译器在副本上创建信号量的新副本-您可以使用任何调试工具测试此理论,以验证信号量确实是相同\不同的对象。

    但更好的解决方案是将其作为指针传递,以确保它不依赖于编译器:

    #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;
    }
    

    在同一个编译器上测试和工作-我认为这是一个更安全的解决方案 希望这会有所帮助