zoukankan      html  css  js  c++  java
  • 心跳

    /// Heartbeat for the World
    void WorldRunnable::run()
    {
    ///- Init new SQL thread for the world database
    WorldDatabase.ThreadStart(); // let thread do safe mySQL requests (one connection call enough)
    sWorld.InitResultQueue();

    uint32 realCurrTime = 0;
    uint32 realPrevTime = WorldTimer::tick();

    uint32 prevSleepTime = 0; // used for balanced full tick time length near WORLD_SLEEP_CONST

    ///- While we have not World::m_stopEvent, update the world
    while (!World::IsStopped())
    {
    ++World::m_worldLoopCounter;
    realCurrTime = WorldTimer::getMSTime(); //----------------(1)

    uint32 diff = WorldTimer::tick(); //--------------(2)

    sWorld.Update( diff ); //--------------(3)
    realPrevTime = realCurrTime;

    // diff (D0) include time of previous sleep (d0) + tick time (t0)
    // we want that next d1 + t1 == WORLD_SLEEP_CONST
    // we can't know next t1 and then can use (t0 + d1) == WORLD_SLEEP_CONST requirement
    // d1 = WORLD_SLEEP_CONST - t0 = WORLD_SLEEP_CONST - (D0 - d0) = WORLD_SLEEP_CONST + d0 - D0
    if (diff <= WORLD_SLEEP_CONST+prevSleepTime) //----------------(4)
    {
    prevSleepTime = WORLD_SLEEP_CONST+prevSleepTime-diff;
    ACE_Based::Thread::Sleep(prevSleepTime);
    }
    else
    prevSleepTime = 0;

    #ifdef WIN32
    if (m_ServiceStatus == 0) World::StopNow(SHUTDOWN_EXIT_CODE);
    while (m_ServiceStatus == 2) Sleep(1000);
    #endif
    }

    sWorld.KickAll(); // save and kick all players
    sWorld.UpdateSessions( 1 ); // real players unload required UpdateSessions call

    // unload battleground templates before different singletons destroyed
    sBattleGroundMgr.DeleteAllBattleGrounds();

    sWorldSocketMgr->StopNetwork();

    sMapMgr.UnloadAll(); // unload all grids (including locked in memory)

    ///- End the database thread
    WorldDatabase.ThreadEnd(); // free mySQL thread resources
    }

    (1)从WorldTimer::getMSTime()得到一个uint32的值realCurrTime,realCurrTime是循环的(到增加到0xFFFFFFFF后,在增加就变成0),表示当前时间,单位是毫秒,是一个相对前一次tick的时间。

    (2)使用WorldTimer::tick();计算上次tick到这次tick的时间差diff,该值理论上等于realCurrTime – realPrevTime

    (3)sWorld.Update( diff );就是tick里的处理函数,游戏逻辑在这里得到更新处理。

    (4)这里就是图1-2中的“图C”所描述的,如果运行时间大于固定的tick时间,则不sleep继续占用CPU来处理更新,直到能在一个tick处理所有操作为止,这个时候才会sleep让出CPU时间片。

    (5)WORLD_SLEEP_CONST就是固定的tick的时间长度,在这里是50ms

        总结:现在可以回答本节前面的两个问题:在高负荷情况下mangos采用图1-2中“图C”的方式提高服务器的响应速度,每个tick时间长度为50ms,也就是每秒钟更新20次,能满足更新的需求。

  • 相关阅读:
    Codeforces1070 2018-2019 ICPC, NEERC, Southern Subregional Contest (Online Mirror, ACM-ICPC Rules, Teams Preferred)总结
    Codeforces 633H Fibonacci-ish II【线段树】
    一些Fibonacci数列的神奇性质【数学】
    Codeforces 620E New Year Tree【线段树傻逼题】
    Codeforces 828C String Reconstruction【并查集巧妙运用】
    Codeforces 559C Gerald and Giant Chess【组合数学】【DP】
    Codeforces 311B Cats Transport【斜率优化DP】
    BZOJ2933 [Poi1999]地图【区间DP】
    BZOJ3688 折线统计【树状数组优化DP】
    BZOJ2131 免费的馅饼【线段树优化DP】
  • 原文地址:https://www.cnblogs.com/yunfeioliver/p/8193590.html
Copyright © 2011-2022 走看看