Pthread中的并发性

时间:2013-02-18 02:58:05

标签: c linux pthreads

我在Linux内核2.6.18-194中运行了ac程序,服务器有1个cpu套接字,其中6个内核带有超线程,thread1接收数据,然后thread2和thread3将接收到的数据thread1传递给另一个进程,在两个thread2之后和thread3成功完成传递数据,thread1将再次接收数据!!

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函数有关吗?

1 个答案:

答案 0 :(得分:2)

正如我的评论中所提到的,无论你是否使用互斥锁,你都有一个竞争条件,semfinished semphore可以发布两次,这意味着thread1可能不允许线程在未来的一轮结束。

很容易看到thread2thread3可以同时“到达”pthread_mutex_lock()来电之前的空白行。如果发生这种情况,那么两个线程都会调用sem_post(semfinished)

为了避免这种情况并使代码更易于推理,使其成为可以确定thread2thread3 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) ;