floowing是thread1源:
DoGetDataFromSocket() ;
iGlbBOOKReadDone = 0 ;
iGlbPOSIReadDone = 0 ;
sem_post(sembook) ;
sem_post(semposi) ;
sem_wait(semfinished) ;
以下是thread2和thread3源:
if(bThisThreadIsBook==1)
sem_wait(sembook) ;
else
sem_wait(semposi) ;
DoPassDatatoAnotherProcess() ;
if(bThisThreadIsBook==1)
{
__sync_add_and_fetch(&iGlbBOOKReadDone,1) ;
}
else
{
__sync_add_and_fetch(&iGlbPOSIReadDone,1) ;
}
Pthread_mutex_lock(&DoneMutex) ;
if( (iGlbBOOKReadDone == 1) && (iGlbPOSIReadDone == 1) )
sem_post(semfinished) ;
Pthread_mutex_unlock(&DoneMutex) ;
它对我很好,我尝试删除thread2和thread3中的mutex_lock DoneMutex,它仍然正常,我很好奇,如果thread2正在执行__sync_add_and_fetch(& iGlbBOOKReadDone,1),并且thread3正在执行__sync_add_and_fetch( &安培; iGlbPOSIReadDone,1) 在完全相同的时间,然后两个线程将if((iGlbBOOKReadDone == 1)&&(iGlbPOSIReadDone == 1))变为false,并且sem_post(semfinished)永远不会被调用, 但我做了很多压力测试,这绝不会发生!它与__sync_add_and_fetch函数有关吗?
答案 0 :(得分:2)
正如我的评论中所提到的,无论你是否使用互斥锁,你都有一个竞争条件,semfinished
semphore可以发布两次,这意味着thread1
可能不允许线程在未来的一轮结束。
很容易看到thread2
和thread3
可以同时“到达”pthread_mutex_lock()
来电之前的空白行。如果发生这种情况,那么两个线程都会调用sem_post(semfinished)
。
为了避免这种情况并使代码更易于推理,使其成为可以确定thread2
和thread3 will call
sem_post(semfinished)`中的一个,您可能需要考虑做类似以下的事情:
线程1:
DoGetDataFromSocket() ;
threadDoneCount = 0;
sem_post(sembook) ;
sem_post(semposi) ;
sem_wait(semfinished) ;
thread2和thread3:
if(bThisThreadIsBook==1)
sem_wait(sembook) ;
else
sem_wait(semposi) ;
DoPassDatatoAnotherProcess() ;
int doneCount = __sync_add_and_fetch(&threadDoneCount,1) ;
if (doneCount == 2)
sem_post(semfinished) ;