当前位置: 首页 > 知识库问答 >
问题:

理解pthread_cond_wait()和pthread_cond_signal()

漆雕育
2023-03-14

一般来说,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);

步骤是

>

线程2锁定互斥锁并调用pthread\u cond\u signal(),从而解锁互斥锁

在线程1中,调用pthread\u cond\u wait(),并再次锁定互斥锁

现在在线程2中,在调用pthread\u cond\u signal()之后,pthread\u mutex\u unlock(

此外,在我看来,pthread\u cond\u wait()。但有一种说法是“pthread_cond_signal()函数应解除阻塞指定条件变量cond上阻塞的至少一个线程(如果任何线程在cond上阻塞)。”那么,这意味着对于同一个cond互斥对,多个线程可以调用pthread\u cond\u wait()


共有3个答案

鲜于玮
2023-03-14

我在这里举了个例子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测试线程。c-LPTThread

等待条件变量cond

信令条件可变条件

返回线程

只有当blockThread的pthread_cond_wait()函数发出解除阻塞的信号时,才会锁定和解锁线程。

朱和惬
2023-03-14

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

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

pthread_mutex_t mutex;
pthread_cond_t condition;

线程1:

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);

线程2:

pthread_mutex_lock(&mutex);

/* do something that may fulfill the condition */

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

编辑

正如您在pthread_cond_wait手册中看到的:

它以原子方式释放互斥锁,并导致调用线程阻塞条件变量cond;原子性在这里意味着“原子性地涉及到另一个线程对互斥体的访问,然后是对条件变量的访问”。

明安阳
2023-03-14

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

pthread\u cond\u wait在互斥体Hibernate之前解锁(如您所注意的),但当发出信号时,它会在唤醒之前重新请求互斥体(可能需要等待)。因此,如果信令线程持有互斥锁(通常情况下),等待线程将不会继续,直到信令线程也解锁互斥锁。

条件变量的常见用法如下:

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);

这两个线程有一些共享的数据结构,互斥体保护对这些结构的访问。第一个线程希望等待某个条件为真,然后立即执行某个操作(没有争用条件机会让其他线程在条件检查和操作之间进入,并使条件为假)第二个线程正在做一些可能使条件变为真实的事情,因此它需要唤醒可能正在等待它的任何人。

 类似资料:
  • 我有多个读线程和一个写线程。如果我锁定其中一个读线程上的互斥体并从中发送广播,是否可以保证互斥体将由等待pthread_cond_wait()的写线程锁定,或者另一个正在等待pthread_mutex_lock()的读线程将锁定互斥体?主要问题是pthread_cond_wait()是否比pthread_mutex_lock()具有优先级? 如果不是,如何实现互斥锁始终由pthread_cond_

  • 我在用C来解决这个问题。 代码是使用编译的。 整个解决方案都在github上。存储库包含两个cpp文件:main。cpp和哲学家。cpp。“Main.cpp”创建互斥变量、信号量、5个条件变量、5个分叉并启动。信号量仅用于同步开始时间。其他参数被传递给哲学家来解决问题。“哲学家.cpp”包含给定问题的解决方案,但经过几个步骤后,死锁就会发生。 当哲学家0正在吃饭,而哲学家1(在他旁边)想要拿叉子时

  • 假设一个线程在条件变量上阻塞: 互斥锁被解锁,尝试锁定互斥锁的其他线程被解锁: 同时还有另一个线程正在等待获取关键部分的所有权: 现在的问题是:调用pthread_cond_signal()时,是否保证pthread_cond_wait()[1]将在pthread_mutex_lock()[2]之前解除阻塞? POSIX规范似乎没有说明这种情况。

  • 问题内容: 我正在尝试实现2个线程。我的测试代码试图使用两个线程来执行以下方案: 线程B等待条件 线程A打印“ Hello”五次 线程A通知线程B 线程A等待 线程B打印“再见” 线程B向线程A发出信号 循环开始(x5) 到目前为止,代码将打印“ Hello”五次,然后卡住。从我看过的示例中,我似乎走对了,“锁定互斥锁,等待,由其他线程发出信号,解锁互斥锁,执行操作,循环” 测试代码: 朝着正确方

  • 我对node.js比较熟悉,编写一个程序时需要承诺异步API调用。我有一个关于执行一些示例代码的问题,这是我在研究中偶然发现的。 下面的代码(根据我的理解)将访问一个API,等待响应,然后将该响应解析为承诺。这是迭代完成的,每个创建的承诺都被传递到一组承诺中。最终,对许诺数组调用promise.all()和.then(),将执行更多代码来迭代数组并将图像添加到页面中。 这里我不理解的是promis

  • 我正在学习模板元编程,最近,我在CPP会议上看到了一个关于void_t的演讲。不久之后,我发现了检测成语。 然而,我仍然很难理解其中的任何一个(尤其是检测习惯用法,因为它基于void_t)。我看了这篇博文,还有这篇stackoverflow的帖子,对我有一点帮助,但是我还是有一些疑问。 如果我的理解是正确的,如果void_t中的表达式无效,它将使用以下表达式被SFINAEd除名: 因为class在