STD优先级队列何时比较值?

发布于 2025-01-26 10:57:13 字数 722 浏览 0 评论 0原文

我有一个优先级队列,比较函数引用了多个线程访问的值。因此,它必须由静音保护。除了我不知道该比较函数何时运行。当我推动值还是弹出值时,它是运行的吗?下面的示例代码。

#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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

呆橘 2025-02-02 10:57:13

要回答这个问题,如果没有记录任何事情,可能会发生任何事情(然后我们就无法推理何时调用比较器)。

如果我们研究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 invokes pop_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).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文