Multithreading 条件变量真的需要另一个变量吗? 我会给出C++的例子,但是我相信我的问题是语言不可知的。如果我错了,请纠正我
只是想让你真正了解我-我在这里试图学习的是工具的功能,而不是其他。不是它通常用来做什么,不是惯例所说的,只是钝器工具所做的。在本例中-条件变量的作用 到目前为止,在我看来,这是一种简单的机制,允许线程等待(阻塞),直到其他线程发出信号(解除阻塞)。除此之外,无需处理关键部分访问或数据访问(当然,它们可以用于此,但这只是程序员的选择问题)。此外,信号通常仅在发生重要事件(如加载数据)时才发出,但理论上可以随时调用。到目前为止正确吗 现在,我看到的每个示例都使用一个条件变量对象(例如Multithreading 条件变量真的需要另一个变量吗? 我会给出C++的例子,但是我相信我的问题是语言不可知的。如果我错了,请纠正我,multithreading,language-agnostic,condition-variable,Multithreading,Language Agnostic,Condition Variable,只是想让你真正了解我-我在这里试图学习的是工具的功能,而不是其他。不是它通常用来做什么,不是惯例所说的,只是钝器工具所做的。在本例中-条件变量的作用 到目前为止,在我看来,这是一种简单的机制,允许线程等待(阻塞),直到其他线程发出信号(解除阻塞)。除此之外,无需处理关键部分访问或数据访问(当然,它们可以用于此,但这只是程序员的选择问题)。此外,信号通常仅在发生重要事件(如加载数据)时才发出,但理论上可以随时调用。到目前为止正确吗 现在,我看到的每个示例都使用一个条件变量对象(例如std::con
std::condition_variable
),但也使用一些附加变量来标记是否发生了什么事情(例如bool datawasload
)。请从以下方面查看此示例:
这不全是虚假的觉醒 当您调用
m_condvar.wait
时,您如何知道等待的条件尚未发生
可能已经在另一个线程中调用了“loadData”。当它调用notify_one()
时,由于没有线程等待,所以什么也没有发生
现在,如果您调用condvar.wait
,您将永远等待,因为没有任何信号会通知您
原始版本没有此问题,因为:
m_bDataLoaded
为false,则它知道数据未加载,并且在m_bDataLoaded
设置为true后,调用者将发出条件信号李>
m_bDataLoaded
不能在另一个线程中修改,直到它被释放李>
condvar.wait
将在释放锁之前将当前线程放入等待队列中,因此我们知道m_bDataLoaded
将在开始等待后设置为true,因此在开始等待后也将调用notify_one
- 是的,与其他变量的协调是条件变量绑定到互斥体的原因
- 比如说,API不需要布尔变量,因为这并不总是您所等待的条件
Task *getTask() {
//anyone who uses m_taskQueue or m_shutDown must lock this mutex
unique_lock<mutex> lock(m_mutex);
while (m_taskQueue.isEmpty()) {
if (m_shutdown) {
return null;
}
// this is signalled after a task is enqueued
// or m_shutdown is asserted
m_condvar.wait(lock);
}
return taskQueue.pop_front();
}
Task*getTask(){
//使用m_taskQueue或m_shutDown的任何人都必须锁定此互斥锁
唯一的_锁(m_互斥锁);
while(m_taskQueue.isEmpty()){
如果(m_关闭){
返回null;
}
//这是在任务排队后发出的信号
//或m_shutdown被断言
m_condvar.等待(锁定);
}
返回taskQueue.pop_front();
}
在这里,我们需要同样的关键保证,即线程在释放锁之前开始等待,但我们等待的条件更复杂,涉及一个变量和单独的数据结构,并且有多种方法退出等待 好吧,虽然我承认在大多数情况下可能需要额外的变量,但我认为仍然有一些场景不需要它们(即使这些场景对任何实际情况都没有用处)。就像在我提供的第二个示例中,我们知道一切都将以正确的顺序运行(除非
mainTask
以某种方式延迟超过1秒,并在notify\u one
之后开始等待,我不知道这是否可能)。我的假设正确吗?当然,但你怎么知道主任务延迟不超过一秒钟?依赖那样的东西是危险的。你能提供2个问题的答案吗。三,。在我最初的帖子中?当然,没有问题API不能要求任何类型的变量(使用模板或其他什么)?
#include <iostream>
#include <thread>
#include <functional>
#include <mutex>
#include <condition_variable>
using namespace std::placeholders;
class Application
{
std::mutex m_mutex;
std::condition_variable m_condVar;
public:
Application()
{
}
void loadData()
{
// Make This Thread sleep for 1 Second
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
std::cout << "Loading Data from XML" << std::endl;
// Lock The Data structure
std::lock_guard<std::mutex> guard(m_mutex);
// Notify the condition variable
m_condVar.notify_one();
}
void mainTask()
{
std::cout << "Do Some Handshaking" << std::endl;
// Acquire the lock
std::unique_lock<std::mutex> mlock(m_mutex);
// Start waiting for the Condition Variable to get signaled
// Wait() will internally release the lock and make the thread to block
// As soon as condition variable get signaled, resume the thread and
// again acquire the lock. Then check if condition is met or not
// If condition is met then continue else again go in wait.
m_condVar.wait(mlock);
std::cout << "Do Processing On loaded Data" << std::endl;
}
};
int main()
{
Application app;
std::thread thread_1(&Application::mainTask, &app);
std::thread thread_2(&Application::loadData, &app);
thread_2.join();
thread_1.join();
return 0;
}
Task *getTask() {
//anyone who uses m_taskQueue or m_shutDown must lock this mutex
unique_lock<mutex> lock(m_mutex);
while (m_taskQueue.isEmpty()) {
if (m_shutdown) {
return null;
}
// this is signalled after a task is enqueued
// or m_shutdown is asserted
m_condvar.wait(lock);
}
return taskQueue.pop_front();
}