我目前对以下代码为何无法打印以下代码感到困惑:
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;
}
答案 0 :(得分:3)
当条件等待或发出信号时,必须在锁定下完成,否则行为是不可预测的,因为它可能进入竞争状态。因此,您的代码应如下所示:
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%安全,因为主线程可以在子线程调用wait之前发出信号。虽然由于主函数中的sleep()
,这里非常不可能,但通常应该有一个变量来识别是否实际需要等待。换句话说,条件不是队列,但可用于创建队列。