我有一个task
课,我需要移动。我有大约10-15个任务包含在task_storage
父类中。在task::execute()
内,我需要等待原子变量达到零:
void task::execute()
{
for_subtasks([this]
{
thread_pool.post([this]
{
this->do_work();
// Atomic counter.
--(this->_remaining_subtasks);
});
});
// wait for `_remaining_subtasks == 0`
}
在保持_remaining_subtasks == 0
可移动的同时,我想到了等待task
的三种选择:
使用while(...){ sleep(1); }
忙等待循环。
在函数内部构造并使用std::mutex
和std::condition_variable
。
void task::execute()
{
std::mutex m;
std::condition_variable cv;
for_subtasks(/* ... */);
std::unique_lock<std::mutex> l(m);
cv.wait(l, [this]{ return this->_remaining_subtasks == 0; });
}
将std::unique_ptr<std::mutex>
和std::unique_ptr<std::condition_variable>
作为字段存储在task
内。这将允许task
可移动,但也引入间接访问同步原语。
void task::execute()
{
for_subtasks(/* ... */);
std::unique_lock<std::mutex> l(*this->_m);
this->_cv.wait(l, [this]{ return this->_remaining_subtasks == 0; });
}
我不打算使用忙碌的等待。我尝试在2到3之间分析最快的解决方案,但无法获得任何有意义的结果。
std::mutex
和std::condition_variable
的构建开销是否显着?或者堆分配/访问会更慢吗?
答案 0 :(得分:1)
std :: mutex和std :: condition_variable的构造开销是否显着?或者堆分配/访问会更慢?
在这两种情况下都必须调用构造函数。不同之处在于分配内存的位置:静态存储,堆栈或堆。堆分配是最慢的。
在Linux和POSIX兼容系统上,std::mutex
和std::condition_variable
是POSIX pthread_mutex_t
和pthread_cond_t
结构上的瘦包装器。初始化这些结构涉及设置基本类型的成员变量而不是调用。换句话说,建筑很便宜。