最近我读了一些关于线程互斥的代码,相关的代码在这里:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
pthread_mutex_t mutex;
pthread_cond_t cond;
pthread_t thread;
void fn(void *arg)
{
3 pthread_mutex_lock(&mutex);
printf( "signal before\n" );
4 pthread_cond_signal(&cond);
printf( "signal after\n" );
pthread_mutex_unlock(&mutex);
}
int main()
{
int err1;
pthread_mutex_init(&mutex, NULL);
pthread_cond_init(&cond,NULL);
1 pthread_mutex_lock(&mutex);
2 err1 = pthread_create(&thread, NULL, fn, NULL);
usleep(1);
pthread_cond_wait(&cond,&mutex);
printf( "main thread get signal\n");
pthread_mutex_unlock(&mutex);
pthread_join(thread, NULL);
pthread_mutex_destroy( &mutex );
pthread_cond_destroy( &cond );
}
在主线程中,首先我调用pthread_mutex_lock
函数锁定num 1中的互斥锁,在我在num 2中创建子线程后,在子线程启动函数void fn( void *arg)
中调用{{1}再次在num 3中,理论上应该阻塞直到释放互斥锁(主线程),但是为什么它可以继续在子线程中执行num 4中的代码?
配置: - prefix = / Applications / Xcode.app / Contents / Developer / usr --with-gxx-include-dir = / Applications / Xcode.app / Contents / Developer / Platforms / MacOSX.platform / Developer /SDKs/MacOSX10.11.sdk/usr/include/c++/4.2.1 Apple LLVM版本7.3.0(clang-703.0.31) 目标:x86_64-apple-darwin15.4.0 线程模型:posix InstalledDir:/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
非常感谢。
答案 0 :(得分:1)
条件变量的目的是允许线程等待其他线程中发生的事情。使用互斥锁执行此操作的问题在于以下代码无效:
糟糕。现在我们在等待锁定时等待。所以没有其他线程可以改变共享状态。所以我们会永远等待。让我们再试一次,这次释放锁:
所以我们需要一个原子&#34;解锁并等待&#34;功能使第2步工作。 pthread_cond_wait
是什么。因此,在线程等待时释放互斥锁。
pthread_cond_wait
的规范用法是:
pthread_mutex_lock(&mutex);
while (we_need_to_wait)
pthread_cond_wait(&cond, &mutex);
// possibly do some stuff while we still hold the mutex
pthread_mutex_unlock(&mutex);
注意这允许我们决定等待我们仍然持有互斥锁,等待而不保持互斥锁,但是没有窗口可以解除互斥条件,其中互斥锁被释放但我们还没有等待。
顺便说一句,任何其他方式使用条件变量都非常困难。所以你真的不应该尝试在任何其他模式中使用pthread_cond_wait
,直到你对条件变量的工作原理有了深刻的理解。确保您始终确切地知道您正在等待的内容以及您等待的内容受到传递给pthread_cond_wait
的互斥锁的保护。