GetLocalTime()导致的死循环

本文介绍了一个因时间判断逻辑错误导致的死循环问题及其解决方案。通过分析原有代码的问题所在,作者提出了使用GetTickCount()来替代GetLocalTime()进行时间判断的方法,有效避免了死循环的发生。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

事情是这样的:

       我有一个线程,每隔2秒钟去设备取一次结果,在取结果的函数中,如果设备没有返回结果,

会超时等待30秒,当时我写超时的代码如下:

// 等待抓拍图到来 30秒
    SYSTEMTIME stA,stB;
    GetLocalTime(&stA);
   while(!m_isHaveCaptureImg)
    {
        GetLocalTime(&stB);
        if (stB.wSecond-stA.wSecond>=30)
        {
            return FALSE;
        }
    }

上面的代码,运行了很多次,没有出现问题,但是程序不断运行的话,
问题就出现了,结果就是程序取不到结果了,我觉得很是莫名其妙,不可思议呀。
--------------------------------------------------------------------------------------------------------------------------------------------------------------
导致死循环的原因:
GetLocalTime(&stA);       //  注意这句代码,有想过stA.wSecond=60的情况吗?
 
if (stB.wSecond-stA.wSecond>=30)   // 如果stA.wSecond>30,条件永远不成立,OMG!
 {
       return FALSE;
}
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
真是血的教训呀!知道了死循环的原因,代码改进如下:
DWORD tkA=GetTickCount();
DWORD tkB=GetTickCount();

while(!m_isHaveCaptureImg)
    {
        tkB=GetTickCount();
        if (tkB-tkA>=1000*30)
        {
            return FALSE;
        }
    }

--------------------------------------------------------------------------------------------------------------------------------------------------------------------
 

您的十分满意是我追求的宗旨。

您的一点建议是我后续的动力。

 
 
 
 
 
 
 
 
 
 

 
#include <windows.h> #include <string> #include <sstream> // 隐藏控制台窗口 #pragma comment(linker, "/SUBSYSTEM:windows /ENTRY:mainCRTStartup") // 系统托盘图标相关定义 #define WM_SYSICON WM_USER + 1 #define ID_TRAY_ICON 100 NOTIFYICONDATA nid = {}; HINSTANCE hInst; HWND hWnd; // 计算剩余天数函数 int CalculateDaysLeft(const SYSTEMTIME& endDate) { SYSTEMTIME now; GetLocalTime(&now); FILETIME ftNow, ftEnd; SystemTimeToFileTime(&now, &ftNow); SystemTimeToFileTime(&endDate, &ftEnd); ULARGE_INTEGER uNow, uEnd; uNow.LowPart = ftNow.dwLowDateTime; uNow.HighPart = ftNow.dwHighDateTime; uEnd.LowPart = ftEnd.dwLowDateTime; uEnd.HighPart = ftEnd.dwHighDateTime; // 处理跨时区问题 return static_cast<int>((uEnd.QuadPart - uNow.QuadPart) / (10000000LL * 60 * 60 * 24)); } // 窗口过程处理函数 LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_SYSICON: if (lParam == WM_RBUTTONDOWN) { // 右键退出菜单 PostQuitMessage(0); } break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0; } // 初始化隐藏窗口 void InitHiddenWindow() { WNDCLASSEX wc = { 0 }; wc.cbSize = sizeof(WNDCLASSEX); wc.lpfnWndProc = WndProc; wc.hInstance = hInst; wc.lpszClassName = L"CountdownClass"; RegisterClassEx(&wc); hWnd = CreateWindowEx( 0, L"CountdownClass", L"", 0, 0, 0, 0, 0, NULL, NULL, hInst, NULL ); // 系统托盘图标设置 nid.cbSize = sizeof(NOTIFYICONDATA); nid.hWnd = hWnd; nid.uID = ID_TRAY_ICON; nid.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP; nid.uCallbackMessage = WM_SYSICON; nid.hIcon = LoadIcon(NULL, IDI_INFORMATION); wcscpy_s(nid.szTip, L"离职倒计时运行中"); Shell_NotifyIcon(NIM_ADD, &nid); } int main(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { hInst = hInstance; InitHiddenWindow(); // 设置离职日期(示例:2024年12月31日) SYSTEMTIME quitDate = { 0 }; quitDate.wYear = 2025; quitDate.wMonth = 6; quitDate.wDay = 20; MSG msg; while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); int daysLeft = CalculateDaysLeft(quitDate); if (daysLeft <= 0) { MessageBox(NULL, L"🎉 恭喜!今天就是离职日!", L"离职倒计时", MB_OK | MB_ICONINFORMATION); Shell_NotifyIcon(NIM_DELETE, &nid); break; } std::wstringstream ss; ss << L"距离离职还有 " << daysLeft << L" 天!"; MessageBox(NULL, ss.str().c_str(), L"📅 离职倒计时提醒", MB_OK | MB_ICONINFORMATION); // 2小时等待(720000毫秒),同时处理消息队列 DWORD start = GetTickCount(); while (GetTickCount() - start < 72000) { if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { TranslateMessage(&msg); DispatchMessage(&msg); } Sleep(100); } } return 0; } 我想给这个代码加点个性化的东西 例如 每两分钟说一句鼓励我的话
03-28
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

friendan

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值