VC 测试一段程序的运行时间 精确到ms

本文介绍了一种高效的方法来计算程序运行时间,通过使用`QueryPerformanceFrequency`和`QueryPerformanceCounter`函数,确保了精确的时间测量。详细步骤包括声明变量、开始计时、结束计时并计算时间差,最终输出毫秒级的运行时间。

分三个步骤

1:声明变量

LARGE_INTEGER litmp;
_int64 QPart1,QPart2;
double dfMinus,dfFreq, dfTim;
QueryPerformanceFrequency(&litmp);

2 在判断时间的开始位置 开始计时

dfFreq=(double) litmp.QuadPart;
QueryPerformanceCounter(&litmp);
QPart1=litmp.QuadPart;

3 在判断结束位置 读取运行时间

QueryPerformanceCounter(&litmp);
QPart2=litmp.QuadPart;
dfMinus=(double)(QPart2-QPart1);
dfTim = dfMinus/dfFreq*1000;
//显示时间
CString msg4="时间:",msg3,msg5="毫秒";
msg3.Format("%10.9f",dfTim);
CString st = msg4+msg3+msg5;

 

st就是最终输出的 运行时间

转载于:https://www.cnblogs.com/LJWJL/p/5257897.html

<think>好的,我现在要帮用户解决在VC6.0 MFC中实现多线程倒计时程序的问题。用户的需求包括创建包含五个编辑框、两个静态文本和两个按钮的界面,使用AfxBeginThread启动线程进行倒计时,同时处理线程安全退出、优化CPU利用率,并提供详细注释的代码。 首先,我需要回忆MFC界面设计的基本步骤。在资源编辑器中添加控件应该不难,但要注意控件ID的设置,特别是五个编辑框可能需要不同的ID来分别处理输入。比如,用户可能需要输入时、分、秒,或者有其他用途,所以需要明确每个编辑框的作用。 接下来是线程的创建。用户提到使用AfxBeginThread,这属于MFC的工作线程。需要确认如何正确传递参数,尤其是将界面控件的句柄或指针传递给线程函数。线程函数必须是静态成员函数或者全局函数,所以可能需要使用类的成员变量来保存状态。 然后考虑线程安全退出。用户希望安全地终止线程,可能需要设置一个标志变量,比如m_bRunning,通过volatile修饰确保可见性。在线程循环中定期检查这个标志,当需要退出时,设置标志并等待线程结束。可能需要使用事件或信号量来同步,但用户引用的内容提到使用CWinThread的ResumeThread,但这里可能更简单的是用标志位控制。 高精度计时器部分,用户引用的资料中没有直接提到,但通常可以使用多媒体计时器timeSetEvent或者QueryPerformanceCounter。不过,在MFC多线程环境下,可能需要结合WaitForSingleObject或Sleep,但高精度可能需要更复杂的方法。不过用户可能接受1秒的精度,所以使用Sleep(1000)可能足够,但需要指出这可能不够精确,或者建议其他方法。 CPU利用率优化方面,如果线程中有循环,使用Sleep让出CPU时间片是必要的,避免忙等待消耗CPU资源。用户提到的编辑框更新频率也需要考虑,可能不需要实时更新,每秒一次即可。 代码注释部分需要详细说明每个步骤,特别是线程函数的参数传递、资源释放和同步机制。同时,要注意MFC的界面更新必须在主线程进行,所以在线程中需要用PostMessage发送自定义消息来更新控件,避免直接操作UI元素导致的线程安全问题。 现在需要整合引用中的内容。引用1提到使用CWinThread类,但用户要求用AfxBeginThread,可能属于工作线程。引用2提到创建挂起线程后恢复,但用户可能不需要挂起,直接启动。引用3和4讨论了InitInstance和Run循环的问题,需要注意返回TRUE以确保消息循环运行,但工作线程可能不需要消息循环,所以可能不需要处理这些。引用5关于const指针可能不相关,暂时忽略。 界面设计部分,五个编辑框可能用于显示倒计时的各个部分,比如时、分、秒的输入和显示,或者剩余时间。两个按钮是开始和停止,静态文本作为标签。需要在对话框类中添加对应的控件变量,比如CEdit和CButton的成员变量。 线程函数中,参数传递可能需要将对话框的this指针传递给线程,以便访问成员变量和更新界面。但直接传递this可能不安全,需要确保线程安全。或者使用自定义结构体传递必要的信息,如控件句柄或倒计时时间。 在线程函数内部,循环递减时间并更新编辑框。每次循环检查m_bRunning是否为false,如果是则退出。更新界面时,使用PostMessage发送自定义消息到主窗口,触发界面更新,这样避免跨线程直接操作控件。 停止按钮的处理函数需要设置m_bRunning为false,并等待线程结束。可能需要保存线程句柄,以便WaitForSingleObject等待线程退出,防止资源泄漏。 代码示例部分,需要包括对话框的头文件和实现文件,自定义消息的定义,线程函数的实现,以及消息映射的处理。特别是BEGIN_MESSAGE_MAP和ON_MESSAGE宏的使用,用于处理自定义消息。 可能的错误点包括:未正确传递参数导致访问违规,未正确同步线程状态导致死锁,未正确更新UI导致程序崩溃。需要确保所有UI操作通过消息队列进行,线程安全地传递数据。 最后,代码注释要详细解释每个关键步骤,特别是线程启动、参数传递、循环检查退出标志、消息发送和UI更新。同时,提醒用户在高精度计时需求下可能需要其他方法,如多媒体计时器,但当前实现以简单为主。 总结步骤:设计界面,添加控件变量;实现线程函数,使用标志位控制退出;通过消息机制更新UI;处理开始和停止按钮的点击事件;确保线程安全退出和资源释放;优化CPU使用率;提供详细注释。</think>根据您的要求,我将分步骤说明如何在VC6.0 MFC中实现多线程倒计时程序,包含完整代码实现和线程安全设计。 一、界面创建步骤 1. 在资源编辑器中创建对话框模板 2. 添加控件: - 5个编辑框(ID:IDC_EDIT1-IDC_EDIT5) - 2个静态文本(IDC_STATIC1/2) - 2个按钮(IDC_START_BTN,IDC_STOP_BTN) 3. 使用ClassWizard为控件关联变量: ```cpp // 头文件声明 CEdit m_editTime; CButton m_btnStart; volatile BOOL m_bRunning; // 线程运行标志 HANDLE m_hThread; // 线程句柄 ``` 二、线程安全实现方案 1. 使用`volatile`修饰运行标志: ```cpp volatile BOOL m_bRunning = FALSE; ``` 2. 通过事件对象同步线程: ```cpp CEvent m_evtStop; // 在对话框类中声明 ``` 三、核心代码实现 ```cpp // 自定义消息定义 #define WM_UPDATE_TIME WM_USER + 100 // 线程参数结构体 struct ThreadParam { CWnd* pWnd; int totalSeconds; }; // 线程处理函数 UINT CountdownThread(LPVOID pParam) { ThreadParam* pData = (ThreadParam*)pParam; int remaining = pData->totalSeconds; while (remaining >= 0 && pData->pWnd->m_hWnd) { if (!m_bRunning) break; // 检查终止标志 // 发送消息更新界面 pData->pWnd->PostMessage(WM_UPDATE_TIME, remaining); remaining--; Sleep(1000); // 精确度可达±15ms[^3] } delete pData; return 0; } // 消息处理函数 BEGIN_MESSAGE_MAP(CMyDialog, CDialog) ON_MESSAGE(WM_UPDATE_TIME, OnUpdateTime) END_MESSAGE_MAP() LRESULT CMyDialog::OnUpdateTime(WPARAM wParam, LPARAM lParam) { int seconds = (int)wParam; CString strTime; strTime.Format(_T("%02d:%02d:%02d"), seconds/3600, (seconds%3600)/60, seconds%60); m_editTime.SetWindowText(strTime); return 0; } // 开始按钮点击处理 void CMyDialog::OnStartBtnClicked() { if (m_bRunning) return; CString strInput; GetDlgItemText(IDC_EDIT_INPUT, strInput); int totalSeconds = _ttoi(strInput); ThreadParam* pParam = new ThreadParam{this, totalSeconds}; m_bRunning = TRUE; m_hThread = AfxBeginThread(CountdownThread, pParam)->m_hThread; // 创建线程[^2] } // 停止按钮点击处理 void CMyDialog::OnStopBtnClicked() { if (m_bRunning) { m_bRunning = FALSE; // 设置终止标志 WaitForSingleObject(m_hThread, INFINITE); // 等待线程退出[^1] } } ``` 四、关键优化措施 1. CPU利用率优化: ```cpp // 在循环中使用Sleep(1000)而非空循环 // 配合WaitForSingleObject保证线程及时退出 ``` 2. 线程安全退出: ```cpp // 使用volatile保证标志可见性 // 通过WaitForSingleObject等待线程终止 ``` 五、注意事项 1. 必须使用PostMessage而非SendMessage更新UI,避免死锁[^3] 2. 线程参数必须通过堆内存分配(new/delete) 3. 建议增加输入校验(0-86400秒范围检查) 4. 可添加临界区保护共享数据(如需要多个线程访问)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值