netease-im / NIM_Duilib_Framework

网易云信Windows应用开发框架。
MIT License
2.09k stars 834 forks source link

添加定时任务丢失 #398

Closed fysu closed 2 years ago

fysu commented 2 years ago

问题现象

在提交定时任务的时候,某些时候会丢失 查看源码在添加队列的代码如下

void MessageLoop::AddToIncomingQueue(const PendingTask &task)
{
    // 本方法可能会在另一个线程中被执行,所以必须线程安全
    std::shared_ptr<MessagePump> pump;
    {
        NAutoLock lock(&incoming_queue_lock_);
        bool was_empty = incoming_queue_.empty();
        incoming_queue_.push(task);
        if (!was_empty)
            return;
        // 因为这函数可能是间接地在另一个线程中被调用的,
        // 此时MessageLoop中可能正有任务在运行,
        // 这些任务中可能包含销毁MessageLoop的任务,
        // 为了保证对MessageLoop中的MessagePump引用有效,
        // 这里需要用到引用指针
        pump = pump_;
    }
    pump->ScheduleWork();
}
我感觉问题是在这里:
...code...
bool was_empty = incoming_queue_.empty(); //判读队列是否为空
        incoming_queue_.push(task);//提交一个任务
        if (!was_empty)//判读是否还有任务
            return; //一开始还有任务则不会调用唤醒直接返回
...code...
这里返回了就不会调用pump->ScheduleWork();去唤醒线程执行

预期结果

不知道在其他地方是否有唤醒线程去执行这个队列里的内容,但是测试时确实会出现,希望作者能够改一下 或者说明为什么像这样设计

重现步骤

int main(int argc, char* argv[])
{

    nbase::MessageLoop message_loop_;
    std::thread([&] {
        for (int i = 1; i < 90; i ++) {
            message_loop_.PostNonNestableDelayedTask(stl::bind([](int x) {stl::ggprintln("[{}]", x); },i), stl::TimeDelta::FromSeconds(i));
        }

        }).detach();
    message_loop_.Run();
    printf("\n--message_loop exit--\n");
    getchar();
    return 0;
}

测绘代码出现任务没有被执行

nmgwddj commented 2 years ago

我无法判断该问题是否在 return 时出现。翻阅新版本的 chrome base 发现实现并没有做特殊的改变。您有什么好的想法可以修复该问题吗?

fysu commented 2 years ago

测试环境的问题,具体问题在我本地开发环境的queue队列,在深度cpy的时候出现问题,感谢作者的开源.