【问题标题】:Understanding pthread了解 pthread
【发布时间】:2017-03-10 23:04:54
【问题描述】:

我目前对为什么以下代码不会打印以下内容感到困惑:

My value is 0
My value is 1
My value is 2

每次我运行此程序时,我要么得到 1-2 行打印,要么什么也没有,程序只是坐在他们的位置,直到我 ctrl-c。我觉得这可能与我使用相同的条件变量和具有 3 个不同线程的互斥锁有关,这是否正确?任何解释都非常感谢。

#include <stdio.h>
#include <pthread.h>
#include <assert.h>
#include <unistd.h>
#include <stdlib.h>

struct id_holder
{
 int id;
};

pthread_mutex_t intersectionMutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t directionCondition = PTHREAD_COND_INITIALIZER;
struct id_holder * holder;

void * logic(void* val)
{
  struct id_holder * id_struct = (struct id_holder *) val;

  pthread_cond_wait(&directionCondition, &intersectionMutex);
  printf("My value is %d\n", id_struct->id);
  free(id_struct);
  return NULL;
}

int main(void)
{
     pthread_t threads[3];

     for(int i = 0; i <3; i++)
     {
       holder = (struct id_holder *) malloc(sizeof(struct id_holder));
       holder->id = i;
       pthread_create(&threads[i], NULL, logic, holder);
     }

     for(int i = 0; i < 3; i++)
     {
       sleep(1);
       pthread_cond_signal(&directionCondition);
     }

     for(int i = 0; i < 3; i++)
     {
       pthread_join(threads[i], NULL);
     }

     return 0;
}

【问题讨论】:

    标签: c pthreads mutex condition-variable


    【解决方案1】:

    当条件被等待或发出信号时,它必须在锁下完成,否则行为是不可预测的,因为它可能进入竞争条件。因此,您的代码应如下所示:

    pthread_mutex_lock(&intersectionMutex);
    pthread_cond_wait(&directionCondition, &intersectionMutex);
    pthread_mutex_unlock(&intersectionMutex);
    

    main 也是一样的(如果你愿意,你可以把锁移到循环之外):

    for(int i = 0; i < 3; i++) {
        sleep(1);
        pthread_mutex_lock(&intersectionMutex);
        pthread_cond_signal(&directionCondition);
        pthread_mutex_unlock(&intersectionMutex);
    }
    

    代码仍然不是 100% 安全的,因为主线程可以在子线程调用等待之前发出条件信号。尽管由于 main 函数中的sleep(),这里不太可能,但通常应该有一个变量来标识是否实际需要等待。也就是说,条件不是队列,但可以用来创建队列。

    【讨论】:

      猜你喜欢
      • 2020-09-13
      • 1970-01-01
      • 1970-01-01
      • 2017-09-20
      • 2018-04-19
      • 2010-09-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多