理解 pthread_cond_wait()和 pthread_cond_information()

一般来说,pthread_cond_wait()pthread_cond_signal()的名称如下:

//thread 1:
pthread_mutex_lock(&mutex);
pthread_cond_wait(&cond, &mutex);
do_something()
pthread_mutex_unlock(&mutex);


//thread 2:
pthread_mutex_lock(&mutex);
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);

台阶是

  1. pthread_cond_wait(&cond, &mutex);被调用,它就会解锁互斥锁

  2. 线程2锁定互斥对象并调用 pthread_cond_signal(),从而解锁互斥对象

  3. 在线程1中,调用 pthread_cond_wait()并再次锁定互斥量

现在在线程2中,在调用 pthread_cond_signal()之后,pthread_mutex_unlock(&mutex)将要运行,在我看来它想要解锁一个互斥锁,这个互斥锁现在被线程1锁定了。我的理解有什么问题吗?

此外,在我看来,对于相同的 cond-mutex 对,pthread_cond_wait()只能由1个线程调用。但是有一种说法“ pthread _ cond _ sign ()函数应该解除至少一个在指定条件变量 cond 上被阻塞的线程的阻塞(如果有任何线程在 cond 上被阻塞)。”因此,这意味着 pthread_cond_wait()可以被多个线程为同一对 cond-mutex 调用?

133476 次浏览

pthread_cond_signal不解锁互斥对象(它不能解锁互斥对象,因为它没有对互斥对象的引用,所以它怎么知道要解锁什么?)实际上,信号不需要与互斥对象有任何连接; 信令线程不需要持有互斥对象,尽管对于大多数基于条件变量的算法来说,它会持有互斥对象。

pthread_cond_wait在互斥对象睡眠之前解锁它(正如您所注意到的) ,但是当它被发出信号时,在它醒来之前,它需要互斥对象(这可能需要等待)。因此,如果信令线程持有互斥锁(通常情况下) ,等待线程将不会继续,直到信令线程也解锁互斥锁。

条件 vars 的常见用法类似于:

thread 1:
pthread_mutex_lock(&mutex);
while (!condition)
pthread_cond_wait(&cond, &mutex);
/* do something that requires holding the mutex and condition is true */
pthread_mutex_unlock(&mutex);


thread2:
pthread_mutex_lock(&mutex);
/* do something that might make condition true */
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);

这两个线程有一些共享的数据结构,互斥对象正在保护对它们的访问。第一个线程想要等待,直到某个条件为真,然后立即执行一些操作(在条件检查和操作之间没有竞争条件机会,因此条件为假)第二个线程所做的事情可能会使条件为真,因此它需要唤醒任何可能正在等待它的人。

下面是一个典型的例子: 线程1正在等待一个条件,该条件可以由线程2实现

我们使用一个互斥对象和一个条件。

pthread_mutex_t mutex;
pthread_cond_t condition;

第一项:

pthread_mutex_lock(&mutex); //mutex lock
while(!condition){
pthread_cond_wait(&condition, &mutex); //wait for the condition
}


/* do what you want */


pthread_mutex_unlock(&mutex);

第二条:

pthread_mutex_lock(&mutex);


/* do something that may fulfill the condition */


pthread_mutex_unlock(&mutex);
pthread_cond_signal(&condition); //wake up thread 1

编辑

正如你在 < strong > pthread _ cond _ wait Manual中看到的:

它自动释放互斥锁并导致调用线程阻塞条件变量 cond; 这里自动表示“对于另一个线程访问互斥锁然后访问条件变量”。

我以此为榜样 Https://www.geeksforgeeks.org/condition-wait-signal-multi-threading/

改装成这样,

#include <pthread.h>
#include <stdio.h>
#include <unistd.h>


// Declaration of thread condition variable
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;


// declaring mutex
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;


// Thread function
void releaseFun()
{
// Let's signal condition variable cond
printf("Signaling condition variable cond\n");
pthread_cond_signal(&cond);
}


// Thread function
void* blockedThread()
{
// acquire a lock
pthread_mutex_lock(&lock);
printf("Waiting on condition variable cond\n");
pthread_cond_wait(&cond, &lock);
// release lock
pthread_mutex_unlock(&lock);


printf("Returning thread\n");


return NULL;
}


// Driver code
int main()
{
pthread_t tid;


// Create thread 1
pthread_create(&tid, NULL, blockedThread, NULL);


// sleep for 1 sec so that thread 1
// would get a chance to run first
sleep(1);


releaseFun();
// wait for the completion of thread 2
pthread_join(tid, NULL);


return 0;
}

输出: gcc test _ thread.c-lpthread

等待条件变量 cond

信令条件变量

回到主题

只有当 lockThread 的 pthread _ cond _ wait ()函数被发出解锁信号时,线程的锁定和解锁才会发生。