MengRao / fmtlog

fmtlog is a performant fmtlib-style logging library with latency in nanoseconds.
MIT License
807 stars 124 forks source link

关于多线程时间戳乱序问题 #39

Closed ahao1995 closed 2 years ago

ahao1995 commented 2 years ago

采用heap处理多线程时间戳好像有些问题,不知是否是我理解有问题 代码demo如下

#include <vector>
#include <iostream>
struct HeapNode
{
    HeapNode(int t) : cur_time(t) {}
    int cur_time;
};
std::vector<HeapNode> bgThreadBuffers;

void adjustHeap(size_t i)
{
    while (true)
    {
        size_t min_i = i;
        size_t ch = i * 2 + 1;
        size_t end = std::min(ch + 2, bgThreadBuffers.size());
        for (; ch < end; ch++)
        {
            auto h_ch = bgThreadBuffers[ch].cur_time;
            auto h_min = bgThreadBuffers[min_i].cur_time;
            if (h_ch && (!h_min || h_ch < h_min))
                min_i = ch;
        }
        if (min_i == i)
            break;
        std::swap(bgThreadBuffers[i], bgThreadBuffers[min_i]);
        i = min_i;
    }
}
int main()
{
    HeapNode node1(0);
    HeapNode node2(3);
    HeapNode node3(1);
    HeapNode node4(2);
    HeapNode node5(4);
    HeapNode node6(7);
    bgThreadBuffers.push_back(node1);
    bgThreadBuffers.push_back(node2);
    bgThreadBuffers.push_back(node3);
    bgThreadBuffers.push_back(node4);
    bgThreadBuffers.push_back(node5);
    bgThreadBuffers.push_back(node6);

    for (int i = bgThreadBuffers.size() / 2; i >= 0; i--)
    {
        adjustHeap(i);
    }
    std::cout << "--------------end-----------------" << std::endl;
    for (auto node : bgThreadBuffers)
    {
        std::cout << node.cur_time << " ";
    }
    std::cout << std::endl;
}

输出结果为1 2 7 3 4 0 请大佬指教

ahao1995 commented 2 years ago

ch = std::min(i * 2 + 1, bgThreadBuffers.size()),没有对ch做判断

MengRao commented 2 years ago

fmtlog里面的header是一个指针,你的代码里没用到指针,不能照抄adjustHeap。另外你这段代码只是建堆,还没有排序

ahao1995 commented 2 years ago

额说的对,忽略了指针,打扰了...膜拜大佬