1. 背景
win7、win10 专业版 操作系统,硬件环境为工作站,存在线程函数内多个定时器不触发的情况。
但是大部分工作站是可以触发,能正常运行。
2. 代码
#include <iostream>
#include <windows.h>
using namespace std;
DWORD WINAPI ThreadProc(LPVOID lpParameter);
// 主函数
int main()
{
// 创建线程
HANDLE hThread = CreateThread(NULL, 0, &ThreadProc, NULL, 0, NULL); // 创建线程
if (hThread == NULL)
{
printf("无法创建线程");
return 1;
}
else CloseHandle(hThread); // 关闭线程句柄
// 主线程继续执行
Sleep(INFINITE);
return 0;
}
void CALLBACK TimeProcW(HWND hwnd, unsigned int message, unsigned int idTimer, DWORD dwTime) //遥控控制指令发送函数
{
printf("here\n");
}
void CALLBACK TimeProcT(HWND hwnd, unsigned int message, unsigned int idTimer, DWORD dwTime) //遥控控制指令发送函数
{
printf("there\n");
}
void CALLBACK TimeProcThird(HWND hwnd, unsigned int message, unsigned int idTimer, DWORD dwTime) //遥控控制指令发送函数
{
printf("there33\n");
}
// 线程函数
DWORD WINAPI ThreadProc(LPVOID lpParameter)
{
// 设置定时器
SetTimer(NULL, 1, 40, TimeProcW); // 设置定时器,参数:窗口句柄、定时器ID、间隔时间(毫秒)、lpTimerFunc
SetTimer(NULL, 2, 40, TimeProcT);
SetTimer(NULL, 3, 40, TimeProcThird);
MSG msg;
while (GetMessage(&msg, NULL, 0, 0)) // 循环接收消息
{
TranslateMessage(&msg); // 翻译键盘消息
DispatchMessage(&msg); // 分派消息
}
return 0;
}
3. 优化
Windows操作系统在同一时间内只支持一个线程中的一个定时器。当你在一个线程中设置多个定时器时,实际上只有最后一个定时器会被激活。其他的定时器会被忽略。
为了解决这个问题,尝试过以下几个方案:
-
使用多线程:你可以创建多个线程,每个线程只设置一个定时器。这样,每个线程都可以独立地运行,而不会影响其他线程。【可行】
-
使用事件循环:你可以使用事件循环来处理所有的定时器事件。这样,即使有多个定时器,也可以确保所有的定时器都被正确地处理。【本身已是事件循环,还是不触发】
-
使用定时器间隔:如果你需要在同一时间触发多个定时器,你可以考虑使用不同的超时时间。例如,你可以为第一个定时器设置5秒的超时时间,为第二个定时器设置10秒的超时时间,以此类推。这样,即使它们都在同一时间到达,也不会相互影响。【不可行】
4. 解决方法
将多个时间信号函数内处理的业务融合到一个定时器函数中。
void CALLBACK TimeProcW(HWND hwnd, unsigned int message, unsigned int idTimer, DWORD dwTime) //遥控控制指令发送函数
{
printf("here\n");
printf("there\n");
printf("there33\n");
}
// 线程函数
DWORD WINAPI ThreadProc(LPVOID lpParameter)
{
// 设置定时器
SetTimer(NULL, 1, 40, TimeProcW); // 设置定时器,参数:窗口句柄、定时器ID、间隔时间(毫秒)、lpTimerFunc
MSG msg;
while (GetMessage(&msg, NULL, 0, 0)) // 循环接收消息
{
TranslateMessage(&msg); // 翻译键盘消息
DispatchMessage(&msg); // 分派消息
}
return 0;
}