pthread_mutex_unlock()函数将释放由互斥量引用的互斥对象。但是,释放互斥体的方式取决于互斥体的类型属性。如果调用pthread_mutex_unlock()时互斥体引用的互斥体对象上存在线程阻塞,导致互斥体变为可用,则调度策略应确定哪个线程将获取互斥体。
如果互斥体类型为PTHREAD_MUTEX_NORMAL,则不应提供死锁检测。试图重新锁定互斥锁会导致死锁。如果线程试图解锁未锁定的互斥锁或解锁的互斥锁,则会导致未定义的行为。
如果互斥类型为PTHREAD_MUTEX_ERRORCHECK,则应提供错误检查。如果线程试图重新锁定已锁定的互斥锁,则应返回错误。如果线程试图解锁未锁定的互斥锁或已解锁的互斥锁,则应返回错误。
如果互斥体类型为PTHREAD_MUTEX_RECURSIVE,那么互斥体应保持锁定计数的概念。当线程第一次成功获取互斥锁时,锁定计数应设置为1。每次线程重新锁定此互斥锁时,锁定计数应递增1。每次线程解锁互斥锁时,锁定计数应减1。当锁计数达到零时,互斥量将可供其他线程获取。如果线程试图解锁未锁定的互斥锁或已解锁的互斥锁,则应返回错误。
如果互斥体类型为PTHREAD_MUTEX_DEFAULT,则尝试递归锁定互斥体会导致未定义的行为。如果未被调用线程锁定,则试图解锁互斥锁会导致未定义的行为。尝试解锁互斥锁,如果未锁定,则会导致未定义的行为。
我通常更喜欢使用PTHREAD_MUTEX_RECURSIVE互斥量,因为在这种情况下,互斥量在计数达到零时可用,并且调用线程不再在此互斥锁上有任何锁定。
如果互斥体上存在大量争用,则解锁互斥体可能会很慢,因为部分解锁工作正在唤醒等待互斥体的任何线程。 – caf
我认为如果将'pthread_mutex_unlock()'调用移动到'pthread_cond_signal()'的调用上方,将会看到结果会很有趣。没有要求在发信号通知条件变量时(仅在等待它时)持有互斥体,并且我怀疑发生了什么事情是信号引起互斥体的争用,因为立即释放的线程会尝试获取互斥体,信令线程仍然成立。 –
@MichaelBurr好点!我测试了你的建议,现在这个程序快了大约40%。 –