一般来说,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()
?
我在这里举了个例子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()函数发出解除阻塞的信号时,才会锁定和解锁线程。
下面是一个典型示例:线程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;原子性在这里意味着“原子性地涉及到另一个线程对互斥体的访问,然后是对条件变量的访问”。
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在