为了理解pthread条件变量的代码,我编写了自己的版本。它看起来是否正确?我在一个程序中使用它,它的工作,但工作速度惊人得多。最初程序大约需要2.5秒,使用我的条件变量版本只需0.8秒,程序输出也是正确的。但是,我不确定,如果我的实施是正确的。
struct cond_node_t
{
sem_t s;
cond_node_t * next;
};
struct cond_t
{
cond_node_t * q; // Linked List
pthread_mutex_t qm; // Lock for the Linked List
};
int my_pthread_cond_init( cond_t * cond )
{
cond->q = NULL;
pthread_mutex_init( &(cond->qm), NULL );
}
int my_pthread_cond_wait( cond_t* cond, pthread_mutex_t* mutex )
{
cond_node_t * self;
pthread_mutex_lock(&(cond->qm));
self = (cond_node_t*)calloc( 1, sizeof(cond_node_t) );
self->next = cond->q;
cond->q = self;
sem_init( &self->s, 0, 0 );
pthread_mutex_unlock(&(cond->qm));
pthread_mutex_unlock(mutex);
sem_wait( &self->s );
free( self ); // Free the node
pthread_mutex_lock(mutex);
}
int my_pthread_cond_signal( cond_t * cond )
{
pthread_mutex_lock(&(cond->qm));
if (cond->q != NULL)
{
sem_post(&(cond->q->s));
cond->q = cond->q->next;
}
pthread_mutex_unlock(&(cond->qm));
}
int my_pthread_cond_broadcast( cond_t * cond )
{
pthread_mutex_lock(&(cond->qm));
while ( cond->q != NULL)
{
sem_post( &(cond->q->s) );
cond->q = cond->q->next;
}
pthread_mutex_unlock(&(cond->qm));
}
答案 0 :(得分:4)
除了缺少返回值检查之外,还有一些问题需要解决:
sem_destroy
未被调用。cond_node_t
,可能会导致免费使用。进一步评论:
pthread_cond_timedwait
超时所需)可能会导致并发症。答案 1 :(得分:2)
基本上你的策略看起来不错,但是你有一个主要的危险,一些未定义的行为,以及一个挑选:
sem_wait
是可以中断的,所以在重负载或运气不好的情况下,你的线程会被虚假地唤醒。你必须小心翼翼地抓住所有这些malloc
或calloc
修改:实际上,您根本不需要malloc
/ free
。一个局部变量也可以。
答案 2 :(得分:2)
您似乎不尊重此要求:
这些函数以原子方式释放互斥锁并导致调用线程阻塞条件变量cond;这里原子意味着 “原子地关于另一个线程访问互斥锁然后条件变量”。也就是说,如果另一个线程能够获取互斥锁 在即将发布的线程发布之后,在该线程中对pthread_cond_broadcast()或pthread_cond_signal()的后续调用将 表现就好像是在约会阻止线程被阻止之后发布的。
你解锁然后等待。另一个线程可以在这些操作之间做很多事情。
P.S。我不确定自己是否正确地解释了这一段,请随意指出我的错误。