如果释放一个mutex之前并未获取它?

ACE_Thread_Mutex m;
m.release(); //如果此时没有任何线程拥有这个锁?

ACE_Thread_Mutex在linux/unix下一般用的pthread_mutex_t来实现,按man手册来说,如果发生这种情况,pthread_mutex_unlock将会返回一个非0的值EPERM:"The current thread does not hold a lock on mutex”.

但是在windows下情况就很不一样。它调用的是LeaveCriticalSection,按msdn所述,此时不会有任何错误,但是当另一个线程试图调用EnterCriticalSection的时候,将会陷入无限的等待中。按我所测试,不仅是另外的线程会如此,错误的调用LeaveCriticalSection的线程再次调用EnterCriticalSection 也会如此。

啊!昨晚我为了这个一宿没睡好。昨晚为了调试一个timer,写了段简单的测试代码。

int ACE_TMAIN(int argc,ACE_TCHAR* argv[]){
    int counter=0;
    time_t startTime=time(NULL);
    ACE_Thread_Mutex m(ACE_TEXT("mutex1"),NULL);
    ACE_Condition_Thread_Mutex mutex(m);
    while(1){
        ACE_Time_Value tv=ACE_OS::gettimeofday()+ACE_Time_Value(1)    ;
        //m.acquire();
        mutex.wait(&tv);         
        time_t sec=time(NULL)-startTime;
        double v;  
        if(sec !=0) v=counter++/(double)sec;
        //m.release();   
    }
    return 0;
}

我在调用条件变量的wait之前没有acquire相对应的mutex,而ACE_OS::cond_wait在调用WaitForSingleObject之前首先会调用thread_mutex_unlock错误的释放锁。结果是WaitForSingleObject立即就返回了,但是wait在醒来后试图再次获取mutex的时候陷入到了无限的等待中。这是win下特有的现象,linux我同样也试了,不会如此。但是,当一段代码逻辑本身就是错误的时候,不该再奢望它在各个平台下得到同样的结果。

此博客中的热门博文

少写代码,多读别人写的代码

在windows下使用llvm+clang

tensorflow distributed runtime初窥