为了理解pthread条件variables的代码,我写了自己的版本。 它看起来正确吗? 我正在使用它在一个程序,它的工作,但工作惊人的快得多。 程序本来需要大约2.5秒,而我的版本的条件variables只需要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)); }
基本上你的策略看起来不错,但你有一个主要的危险,一些未定义的行为,并挑选一个挑战:
sem_wait
是可以中断的,所以在重载或运气不好的情况下,你的线程将被虚假地唤醒。 你必须小心翼翼地抓住这一切 malloc
或calloc
的返回 编辑:其实,你根本不需要malloc
/ free
。 局部变量也可以。
除了缺少返回值检查之外,还有一些问题应该可以解决:
sem_destroy
不被调用。 cond_node_t
,可能导致免费使用。 进一步评论:
pthread_cond_timedwait
超时所需)可能会导致并发症。 你似乎不尊重这个要求:
这些函数以原子方式释放互斥并导致调用线程在条件变量cond上阻塞; 原子地这里的意思是“原子地相对于另一个线程访问互斥体,然后是条件变量”。 也就是说,如果另一个线程能够在约程序线程释放它之后获取该互斥体,则该线程中的pthread_cond_broadcast()或pthread_cond_signal()的后续调用应该如同在about-阻塞线程被阻塞。
你解锁,然后等待。 另一个线程可以在这些操作之间做很多事情。
PS我不确定自己,如果我正确地解释这一段,随时指出我的错误。