Game server Timer (Timer) Dynamic Link Library [over network]

Source: Internet
Author: User

For game servers, timers (triggered at a specific time) and timers (triggered at a specified point) are indispensable components. There are many timer and timer practices. I roughly divide them into three types:

1. Non-thread timer and timer;

2. Single-thread timer and timer;

3. Implement the timer and timer in multiple threads;

The implementation principles of the three timers are roughly the same. The timestamp gettickcount () is used for comparison, sleep waiting, and waitforsingleobject waiting.

For convenience, I have packaged the timer in DLL. Only the above two timers are encapsulated. I am not optimistic about the multi-thread timer, so I didn't do it. Because the CPU consumption of the timer is very low, thread switching between multiple threads started by the multi-thread timer will consume a lot of CPU.

Unsigned long dwNowTime = GetTickCount (); // timer if (dwNowTime-m_dwPrevTick >=10) {// record the execution time m_dwPrevTick = dwNowTime; map <unsigned short, TIMEINFO> :: iterator it = m_mapTimeInfos.begin (); for (; it! = M_mapTimeInfos.end (); ++ it) {if (0 = it-> second. uElapse) {continue;} unsigned short nCount = (unsigned short) (dwNowTime-(it-> second. dwTick)/(it-> second. uElapse); for (int I = 0; I <nCount; ++ I) {m_listTimerEvents.push_back (it-> first); it-> second. dwTick = dwNowTime; // record the execution time }}// Timer: Run Once every second if (dwNowTime-m_dwPrevTickD >=500) {m_dwPrevTickD = dwNowTime; time_t; time (& t); tm * pNow = localtime (& t); map <unsi Gned short, TIMEINFOD >:: iterator itD = m_mapTimerDInfos.begin (); for (; itD! = M_mapTimerDInfos.end (); ++ itD) {if (itD-> second. stTm. tm_hour = pNow-> tm_hour & itD-> second. stTm. tm_min = pNow-> tm_min & itD-> second. stTm. tm_sec = pNow-> tm_sec & itD-> second. nExeSec! = PNow-> tm_sec) {m_listTimerEvents.push_back (itD-> first); itD-> second. nExeSec = pNow-> tm_sec ;}}// timer Event Callback bool bRun = false; for (unsigned short I = 0; (m_listTimerEvents.size ()> 0) & (I <nLimitedCount); ++ I) {unsigned short nIDEvent = m_listTimerEvents.front (); m_listTimerEvents.pop_front (); if (NULL! = M_pITimer) {m_pITimer-> OnTimer (nIDEvent); bRun = true ;}// core code of implementation (single-thread timer): char szBuffer [0 xFFFF]; // temporarily use while (true) {unsigned long nRet = WaitForSingleObject (m_handleThread, TIMER_WAIT_SINGLE); if (WAIT_OBJECT_0 = nRet) {break; // receives the semaphore, stop thread} if (m_bNeedUpdate) {// update timer information to the timer information list copy m_mapTempTimeInfos.clear (); EnterCriticalSection (& m_crit); m_mapTempTimeInfos = m_mapTimeInfos; m_mapTempTimeDInfos = m_mapTime DInfos; LeaveCriticalSection (& m_crit); m_bNeedUpdate = false;} // executes the timer determination and triggers the queue unsigned long dwNowTime = GetTickCount (); map <unsigned short, TIMEINFO>: iterator it = m_mapTempTimeInfos.begin (); for (; it! = M_mapTempTimeInfos.end (); ++ it) {if (0 = it-> second. uElapse) {continue ;}// determine the time difference between the current cycle and the previous cycle to calculate the number of times the timer unsigned short nCount = (unsigned short) needs to be triggered) (dwNowTime-(it-> second. dwTick)/(it-> second. uElapse); if (nCount> 0) {it-> second. dwTick = dwNowTime; // record the execution time int nFreeLen = m_pipeEvents.GetFreeLen (); // The timer triggers the queue idle length if (nFreeLen> = (int) (sizeof (unsigned short) * nCount) {// writes the number of triggers to the timer to trigger the queue char * pBuf = szBuffe R; int nLen = 0; for (int I = 0; I <nCount; ++ I) {* (unsigned short *) (pBuf + nLen) = it-> first; nLen + = sizeof (unsigned short);} m_pipeEvents.WriteData (szBuffer, nLen) ;}// the timer determines if (dwNowTime-m_dwPrevTickD> = 500) {m_dwPrevTickD = dwNowTime; time_t; time (& t); tm * pNow = localtime (& t); map <unsigned short, TIMEINFOD >:: iterator itD = m_mapTempTimeDInfos.begin (); for (; itD! = M_mapTempTimeDInfos.end (); ++ itD) {if (itD-> second. stTm. tm_hour = pNow-> tm_hour & itD-> second. stTm. tm_min = pNow-> tm_min & itD-> second. stTm. tm_sec = pNow-> tm_sec & itD-> second. nExeSec! = PNow-> tm_sec) {// trigger the timer char * pBuf = szBuffer; int nLen = 0; * (unsigned short *) (pBuf + nLen) = itD-> first; nLen + = sizeof (unsigned short); m_pipeEvents.WriteData (szBuffer, nLen); itD-> second. nExeSec = pNow-> tm_sec ;}}}}

Because of the confidentiality of the company, we did not provide all the source code implemented by DLL. I believe some experienced programmers can do it by themselves (after all, it is best to write it by themselves ). The compressed package contains the compiled DLL and Test Program (developed in vs2008 ).

The efficiency of this Linked Library is very high. During the test, the CPU usage is basically 0%, and occasionally 1% or 2% occurs. If you have any questions or have a better way to achieve, I hope to contact me (hzdiy@126.com), we will discuss the study.

The source code program can be found in the uploaded resources. Http://download.csdn.net/detail/hzdiy/4159100

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.