《Windows API每日一練》7.1 計時器基礎知識

計時器(Timer)是一種在編程中用于測量時間間隔的機制。它允許程序在指定的時間間隔內執行特定的操作或觸發事件。

本節必須掌握的知識點:

??? ????計時器

7.1.1 計時器

我們可以調用SetTimer函數為自己的Windows程序分配一個計時器。SetTimer包含一個無符號整型參數,該參數指定了時間間隔的長短,為一毫秒(millisecond)到4 294 967 295 毫秒(將近50天)。這個參數也表示Windows給程序發送WM_TIMER消息的頻率。例如, 1000毫秒就是要求Windows每一秒鐘向你的程序發送一條WM_TIMER消息。

當程序不再需要計時器時,它可調用KillTimer函數停止計時器的消息。在處理 WM_TIMER消息時調用KillTimer函數可以實現一個“一次性”的計時器。KillTimer函數會淸除消息隊列中任何沒被處理的WM_TIMER消息。調用了 KillTimer之后,程序就不會再收到WM_TIMER消息了。

?????? ■Windows系統計時器

在 Windows 系統中,計時器的實現原理涉及到系統時鐘和消息循環。

Windows 系統中的計時器通常使用以下兩種方式實現:

●基于時間片的計時器(基于輪詢):這種計時器的實現方式是在應用程序的消息循環中以固定時間間隔進行輪詢。應用程序通過在消息循環中處理 WM_TIMER 消息來執行特定的操作。WM_TIMER 消息會周期性地發送給應用程序的消息隊列,以通知計時器事件的發生。

應用程序可以使用 SetTimer 函數來創建一個定時器。該函數指定計時器的時間間隔和回調函數,并返回一個計時器 ID。然后,在消息循環中,應用程序通過處理 WM_TIMER 消息來執行相應的操作。

這種基于時間片的計時器適用于較低精度的計時需求,例如執行周期性的任務或更新用戶界面。

●高精度計時器(Multimedia Timers):對于需要更高精度和準確性的計時需求,Windows 提供了高精度計時器。高精度計時器使用系統時鐘的硬件定時器來實現,提供了更高的計時精度。

應用程序可以使用 timeSetEvent 函數來創建一個高精度計時器。該函數指定計時器的時間間隔、回調函數和其他參數,并返回一個計時器 ID。計時器事件觸發時,系統會調用指定的回調函數。

高精度計時器適用于需要更精確計時的場景,例如音頻和視頻處理、實時數據采集等。

無論是基于時間片的計時器還是高精度計時器,它們的實現都依賴于系統時鐘和消息循環。系統時鐘提供了時間基準,用于確定計時器事件的發生時間。消息循環負責接收和處理計時器相關的消息,以便應用程序可以在計時器事件發生時執行相應的操作。

需要注意的是,計時器的精度可能受到系統負載、硬件性能和操作系統版本等因素的影響。因此,在實際應用中,如果需要更高精度的計時器,可以使用高精度計時器,并進行適當的性能測試和調優。

基于時間片的計時器

Windows的應用程序并不截獲BIOS中斷。Windows本身會處理硬件中斷,應用程序不需介入。對于當前所設定的每一個計時器,Windows都會保持一個計數值,硬件時鐘滴答每出現一次,這個值會減1。當計數值減到0,Windows會把一個WM_TIMER消息放到適當的應用程序的消息隊列中,同時把計數值重新設置回它的原始值。

由于Windows應用程序是通過正常的消息隊列來接收WM_TIMER消息,所以你絕對不用擔心程序在處理其他任務時會被突然而來的WM_TIMER消息所“中斷” 。因此計時器與鍵盤和鼠標相似:驅動程序會處理異步硬件中斷事件,Windows則將這些事件轉換為有序的、有組織的和系列化的消息。

在Windows 98上,計時器具有與底層PC計時器相同的55毫秒的周期。而在Windows NT上,計時器的周期大約是10毫秒。

Windows應用程序不能接收比上述頻率更高的WM_TIMER消息,也就是說在 Windows 98上約為每秒18.2次,而在Windows NT上為每秒100次。Windows會通過 SetTimer把指定的時間間隔舍入到時鐘滴答的整數倍。例如,1000亳秒時間段被54.925除是18.207個時鐘滴答,它被舍入到18個時鐘滴答,因此實際的間隔是989毫秒。如果時間間隔被設置為少于55毫秒,每個時鐘滴答都將產生一個WM_TIMER消息。

?????? ■計時器同步

因為計時器是基于硬件計時器的中斷,程序員有時會被誤導,認為他們的程序可能會被異步中斷打斷后被迫去處理WM_TIMER消息。

其實WM_TIMER消息并不是異步的。WM_TIMER消息被放在正常的消息隊列中,并和其他的消息一同排隊等候處理。因此如果你在調用SetTimer函數時指定1000毫秒,并不能保證程序每秒鐘或者每989毫秒(如我前面說過的)就收到一個WM_TIMER消息。如果你的程序處于忙的狀態超過一秒鐘,它就會在那個時間內得不到任何WM_TIMER消息。本章提供的程序便是證明。事實上,Windows處理WM_TIMER消息和處理WM_PAINT消息很類似。這兩種消息都是低優先級的,只有當消息隊列中沒有其他消息時,程序才會收到它們。

WM_TIMER消息還在另一方面與WM_PAINT消息極為類似。Windows并不會連續不斷地產生多個WM_TIMER消息到消息隊列中。相反,Windows把在消息隊列里的多個 WM_TIMER消息結合成一條消息。這樣,應用程序不會同時收到大量的WM_TIMER消息,盡管它可能會收到靠得很近的兩個WM_TIMER消息。同時,應用程序并不知道有多少這樣的WM_TIMER消息在這個過程中“丟失”了。

因此,一個時鐘程序不能通過計算它所收到的WM_TIMER消息個數來確認已過去多長時間。WM_TIMER消息只能告訴應用程序,更新的時間到了。在本章的后面,我們會寫兩個時鐘程序,它們每秒鐘更新一次,我們將準確地看到它是如何實現的。

為方便起見,我將假設計時器每秒鐘收到一個WM_TIMER消息。但是請記住,這些消息不是精確的時鐘滴答中斷。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/37407.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/37407.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/37407.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

pygame在mobaxterm上無法顯示屏幕

在mobaxterm上的linux系統(這里測試的是ubuntu系統)上運行pygame時,在運行代碼 pygame.display.init()展示窗口時會顯示pygame.error: windows not available的錯誤。 這是因為linux下的窗口展示配置與windows不同,windows下按 …

C++實現簡化版Qt信號槽機制(2):增加內存安全保障

在上一篇文章中《C實現一個簡單的Qt信號槽機制》,我們基于前面的反射代碼實現了信號槽的功能。 但是上一篇的代碼中沒有對象生命周期管理的機制,如果在對象的生命周期結束后還存在未斷開的信號和槽連接,那么信號觸發時可能會嘗試訪問已經被析…

ValidateAntiForgeryToken、AntiForgeryToken 防止CSRF(跨網站請求偽造)

用途&#xff1a;防止CSRF&#xff08;跨網站請求偽造&#xff09;。 用法&#xff1a;在View->Form表單中: aspx&#xff1a;<%:Html.AntiForgeryToken()%> razor&#xff1a;Html.AntiForgeryToken() 在Controller->Action動作上&#xff1a;[ValidateAntiForge…

Java的IO體系

目錄 1、Java的IO體系2、IO的常用方法3、Java中為什么要分為字節流和字符流4、File和RandomAccessFile5、Java對象的序列化和反序列化6、緩沖流7、Java 的IO流中涉及哪些設計模式 1、Java的IO體系 IO 即為 input 輸入 和 output輸出 Java的IO體系主要分為字節流和字符流兩大類…

java對word文檔轉圖片,轉PDF

話不多說&#xff0c;直接入題 先引包 <dependency><groupId>com.luhuiguo</groupId><artifactId>aspose-words</artifactId><version>23.1</version></dependency> word文檔轉圖片 import com.aspose.words.Document; impor…

防爆配電箱航空插頭正確安裝

防爆配電箱航空插頭的安裝確實有特殊要求&#xff0c;這些要求旨在確保配電箱在潛在危險環境中的安全運行。以下是一些關鍵的安裝要求&#xff1a; 安裝環境&#xff1a;防爆配電箱應安裝在危險區域之外的安全地點&#xff0c;遠離潛在的爆炸源和危險物質。安裝環境應保持干燥、…

springboot使用feign調用不依賴cloud

在使用spring boot調用第三方api中&#xff0c;常用的是okhttp、apache http client等&#xff0c;但是直接使用下來還是有點繁瑣&#xff0c;需要手動轉換實體。 在springcloud中有個openfeign調用&#xff0c;第一次體驗到調用接口還能這么絲滑。注解寫道接口上&#xff0c;…

17859劃分準則小結

17859《劃分準則》 發布時間&#xff1a;1999.9.13 實施時間&#xff1a;2001.1.1 計算機信息系統安全保護能力的五個等級&#xff1a; 第一級&#xff1a;用戶自主保護級 第二級…

數據結構簡介

在容器的基礎之上&#xff0c;java引入了數據結構的概念。數據結構可以簡單地理解成是一個以特定的布局方式來存儲數據的容器。但是我個人覺得這種理解方式不太合理&#xff0c;根據我們學的數據結構的內容&#xff0c;我更傾向于數據結構是數據在容器中的布局方式&#xff0c;…

rtthread stm32h743的使用(十一)spi設備使用

我們要在rtthread studio 開發環境中建立stm32h743xih6芯片的工程。我們使用一塊stm32h743及fpga的核心板完成相關實驗&#xff0c;核心板如圖&#xff1a; 1.建立新工程&#xff0c;選擇相應的芯片型號及debug引腳及調試器 2.編譯下載&#xff0c;可以看到串口打印正常 3.…

Python商務數據分析知識專欄(一)——Python編程基礎

Python商務數據分析知識專欄&#xff08;一&#xff09;——Python編程基礎 一、認識python二、編寫python程序三、認識python數據結構四、條件判斷及分支語句五、使用def定義函數六、認識面向對象七、讀取文件數據八、模塊和第三方庫專欄一&#xff08;Python基礎&#xff09;…

c++ 解決區間最大數和矩陣最大面積

給定一個實數序列&#xff0c;設計一個最有效的算法&#xff0c;找到一個總和數最大的區間等于某個事先給定的數字。 我們可以使用前綴和和哈希表來設計一個高效的算法。這個算法的時間復雜度是 O(n)&#xff0c;空間復雜度也是 O(n)。 #include <vector> #include <…

python查找支撐數 青少年編程電子學會python編程等級考試三級真題解析2022年3月

目錄 python查找支撐數 一、題目要求 1、編程實現 2、輸入輸出 二、算法分析 三、程序代碼 四、程序說明 五、運行結果 六、考點分析 七、 推薦資料 1、藍橋杯比賽 2、考級資料 3、其它資料 python查找支撐數 2022年3月 python編程等級考試級編程題 一、題目要求…

RabbitMQ 的經典問題

文章目錄 前言一、防止消息丟失1.1 ConfirmCallback/ReturnCallback1.2 持久化1.3 消費者確認消息 二、防止重復消費三、處理消息堆積四、有序消費消息五、實現延時隊列六、小結推薦閱讀 前言 當設計和運維消息隊列系統時&#xff0c;如 RabbitMQ&#xff0c;有幾個關鍵問題需…

第100+13步 ChatGPT學習:R實現決策樹分類

基于R 4.2.2版本演示 一、寫在前面 有不少大佬問做機器學習分類能不能用R語言&#xff0c;不想學Python咯。 答曰&#xff1a;可&#xff01;用GPT或者Kimi轉一下就得了唄。 加上最近也沒啥內容寫了&#xff0c;就幫各位搬運一下吧。 二、R代碼實現決策樹分類 &#xff08;…

【漏洞復現】宏景HCM人力資源信息管理系統——任意文件讀取漏洞

聲明&#xff1a;本文檔或演示材料僅供教育和教學目的使用&#xff0c;任何個人或組織使用本文檔中的信息進行非法活動&#xff0c;均與本文檔的作者或發布者無關。 文章目錄 漏洞描述漏洞復現測試工具 漏洞描述 宏景HCM人力資源信息管理系統是一款全面覆蓋人力資源管理各模塊…

docker pull 鏡像的時候遇到Pulling fs layer問題

最近遇到一個很奇怪的問題,docker pull 鏡像的時候,總是出現Pulling fs layer問題,導致鏡像拉取不成功,以前是安裝好docker,正常拉取鏡像都是沒什么問題的,在這里記錄一下這個問題的解決方法,當然,可能并不通用。 1、進入阿里云容器服務 地址:https://cr.console.aliy…

Spring Boot中的熱部署配置

Spring Boot中的熱部署配置 大家好&#xff0c;我是免費搭建查券返利機器人省錢賺傭金就用微賺淘客系統3.0的小編&#xff0c;也是冬天不穿秋褲&#xff0c;天冷也要風度的程序猿&#xff01;今天我們將探討如何在Spring Boot項目中實現熱部署配置&#xff0c;提升開發效率和項…

C++實現Qt的信號+槽功能

在 Visual Studio (VS) 上使用 C 實現類似 Qt 的信號和槽機制是完全可能的&#xff0c;但 Qt 的信號和槽系統是基于其特定的元對象系統&#xff08;Meta-Object System, MOC&#xff09;的&#xff0c;這需要一些特定的預處理器和代碼生成步驟。 如果你不想使用 Qt&#xff0c;…

vue路由傳參和react 路由傳參

路由跳轉的方式 1、聲明式導航 <router-link to"導航的地址"> 2、編程式導航 編程式導航有三種方法來進行導航 router.push router.replace router.go params傳參和query傳參 1、 params 傳參(不在URL中顯示參數) 在父路由跳轉到子路由時&#xff0c;也可…