STD优先级队列何时比较值?
我有一个优先级队列,比较函数引用了多个线程访问的值。因此,它必须由静音保护。除了我不知道该比较函数何时运行。当我推动值还是弹出值时,它是运行的吗?下面的示例代码。
#include <iostream>
#include <queue>
#include <mutex>
using namespace std;
int main()
{
int compare = 7;
mutex compare_m;
auto cmp = [&](int a, int b) {return abs(compare - a)>=abs(compare-b);};
priority_queue<int, vector<int>, decltype(cmp)> x(cmp);
mutex x_m;
//in thread
{
scoped_lock m1(x_m);
//do I need this?
scoped_lock m(compare_m);
x.push(6);
}
//in thread
{
scoped_lock m1(x_m);
//do I need this?
scoped_lock m(compare_m);
x.pop();
}
}
I have a priority queue and the compare function references a value accessed by multiple threads. So it has to be protected by a mutex. Except I don't know when this compare function is ran. Is it ran when I push a value or when I pop a value? Example code below.
#include <iostream>
#include <queue>
#include <mutex>
using namespace std;
int main()
{
int compare = 7;
mutex compare_m;
auto cmp = [&](int a, int b) {return abs(compare - a)>=abs(compare-b);};
priority_queue<int, vector<int>, decltype(cmp)> x(cmp);
mutex x_m;
//in thread
{
scoped_lock m1(x_m);
//do I need this?
scoped_lock m(compare_m);
x.push(6);
}
//in thread
{
scoped_lock m1(x_m);
//do I need this?
scoped_lock m(compare_m);
x.pop();
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
要回答这个问题,如果没有记录任何事情,可能会发生任何事情(然后我们就无法推理何时调用比较器)。
如果我们研究cppreference,按 push_heap ,然后将元素重新组织成一个堆。鉴于它需要重组,我们可以认为它会调用比较器。
pop
发生了类似的情况,该调用pop_heap
,它再次修改了基础堆。再次,调用比较器。因此,以上意味着您需要对两者进行关键部分(但是,请注意有关在PQ包含元素时更改比较函数的行为的评论是否实际上是SAFE )。
To answer the question, if it is not documented anything can happen (and then we cannot then reason about when comparator is invoked).
If we take a look into cppreference, push is defined in terms of push_heap, which then reorganizes the elements into a heap. Given it then needs to reorganize, we can reason that it invokes the comparator. A similar situation happens with
pop
, that invokespop_heap
, which again modifies the underlying heap. So again, invoking comparator.So the above implies you need a critical section on both (however please notice the comments regarding whether it is actually safe to change the behaviour of comparison function while the pq contains elements).