如何解决编译器是否允许围绕 `std::condition_variable::notify_one` 重新排序语句?
以下代码是我编写的一个结构体,它允许我将工作排队以在多个工作线程上运行,并且它会阻塞主线程,直到有新的工作线程可用。
struct WorkQueue{
const std::size_t size;
std::vector<uint8_t> threadActive;
std::condition_variable cond;
std::mutex mu;
std::vector<std::jthread> threads;
WorkQueue(std::size_t size_ = 1) :
size{size_}
{
threads.resize(size);
threadActive.resize(size);
std::fill(std::begin(threadActive),std::end(threadActive),false);
}
template<typename Function>
void enqueue(Function&& f){
auto numActiveThreads = [&](){
return std::count(std::begin(threadActive),true);
};
auto availableThread = [&](){
return std::find(std::begin(threadActive),false) - std::begin(threadActive);
};
std::unique_lock<std::mutex> lock{mu};
//wait until a thread becomes available
if(numActiveThreads() == size){
cond.wait(lock,[&](){ return numActiveThreads() != size; });
}
//get an available thread and mark it as active
auto index = availableThread();
threadActive[index] = true;
//start the new thread and swap it into place
std::jthread thread{[this,index,fn = std::forward<Function>(f)](){
fn();
threadActive[index] = false;
cond.notify_one();
}};
threads[index].swap(thread);
}
};
我有两个关于 jthread
执行的 lambda 代码的问题:
-
设置
mu
时是否需要锁定互斥量threadActive[index] = false
? -
是否允许编译器重新排序代码并在设置
cond.notify_one()
之前执行threadActive[index] = false
?
我认为当且仅当允许编译器对语句重新排序时,才需要锁定互斥锁。这是正确的吗?
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。