《定時執行專家》軟體的一個重要的特點就是能夠毫秒級定時執行任務,能夠保證誤差在50毫秒以內,因為毫秒級的觸發要求非常快的時間檢測速度,為了能達到這個要求,我們采用了多執行緒并行處理的方式,
多執行緒的并行處理主要體現在以下兩個功能上:
1、觸發器檢查執行緒,檢查觸發器是否到了觸發時間,這里按照觸發器型別分成了 11個執行緒,并發執行;
2、另外是任務執行執行緒,每個任務的執行都是在新執行緒里面執行的,各個任務都不存在相互等待,
可以通過“觸發器對話框”界面,設定以下四種“秒”級觸發條件:
- 倒計時
- 伴隨軟體啟動
- 空閑時間
- 間隔時間

【使用手冊】
https://blog.csdn.net/boomworks/article/details/116405931
【下載鏈接】
TimingExecutor-V5.6-211218.zip
鏈接:百度網盤 請輸入提取碼
提取碼:boom
// -------------------------------------------------------------------------------------
附:
一、軟體簡介
《定時執行專家》是一款制作精良、功能全面、使用簡單的專業定時執行工具軟體,支持 18 種任務型別,11 種任務觸發方式(包含 Cron方式),觸發精度達到“秒”級,軟體無需安裝,無使用時間限制,歡迎下載使用,軟體使用 Unicode 編碼,可以在英文、日文等所有外文 Windows 系統下正常使用,并且軟體帶有中、日、英多國語言界面版本,可自由切換,
這次版本升級間隔了10多年,在《PC定時執行專家 4.0》的基礎上,做了重大升級和更新,重寫這個軟體,希望這個新版本能在各種應用場景發揮它的作用,

(圖1-1,定時執行專家 - 主視窗)
二、適用人群及應用場景
- 每天作業在電腦前面的白領
- IT管理人員
- 系統維護管理人員
- 程式開發人員
- 辦公室人員
- 有定時播放需求的學校、機關
- 有定時截屏監控需求的場景
三、軟體功能概要
1、支持 18 種任務型別
1) 日程提醒;2) 打開網址;3) 打開檔案夾;4) 打開檔案;5) 備份目錄;6) 執行DOS命令;7) 執行批處理檔案(.bat) ;8) 關閉顯示幕;9) 清慷訓收站;10) 鎖定此電腦;11) 關機;12) 重啟;13) 注銷;14) 睡眠;15) 休眠;16) 發送UDP訊息;17) 自動截屏(截屏并保存到指定目錄);18) 關閉程式
2、支持 11 種觸發方式
1) 倒計時;2) 隨軟體啟動;3) 空閑時間; 4) 間隔時間;5) 具體時間;6) 每小時;7) 每天;8) 每周;9) 每月;10) 每年;11) Cron方式(Cron界面化設定方式,易于使用,可自行百度Cron運算式了解)
* [注] 前 4 種觸發方式,可以指定小時、分鐘、秒種,可以精確執行”秒“級的任務,
* [注] 新功能會不斷更新,詳情請查看作者的博客(軟體關于對話框,有博客鏈接)
【關鍵字/Keyword】
boomworks PC定時執行專家 定時執行專家 定時執行工具 定時執行 定時關機 自動關機軟體 自動關機 關機軟體 定時任務管理 定時任務 任務管理 自動截屏 自動螢屏截圖 螢屏截圖 無察覺截屏 隱身執行 超級網搜 全網搜索 代碼統計工具 代碼統計分析工具 代碼統計 代碼分析
// -------------------------------------------------------------------------------------
附:
一、執行緒池的任務執行機制
任務調度是執行緒池的主要入口,當用戶提交了一個任務,接下來這個任務將如何執行都是由這個階段決定的,了解這部分就相當于了解了執行緒池的核心運行機制,
首先,所有任務的調度都是由execute方法完成的,這部分完成的作業是:檢查現在執行緒池的運行狀態、運行執行緒數、運行策略,決定接下來執行的流程,是直接申請執行緒執行,或是緩沖到佇列中執行,亦或是直接拒絕該任務,其執行程序如下:
首先檢測執行緒池運行狀態,如果不是RUNNING,則直接拒絕,執行緒池要保證在RUNNING的狀態下執行任務,
如果workerCount < corePoolSize,則創建并啟動一個執行緒來執行新提交的任務,
如果workerCount >= corePoolSize,且執行緒池內的阻塞佇列未滿,則將任務添加到該阻塞佇列中,
如果workerCount >= corePoolSize && workerCount < maximumPoolSize,且執行緒池內的阻塞佇列已滿,則創建并啟動一個執行緒來執行新提交的任務,
如果workerCount >= maximumPoolSize,并且執行緒池內的阻塞佇列已滿, 則根據拒絕策略來處理該任務, 默認的處理方式是直接拋例外,
二、軟體定時器實作的思路
軟體開發中,軟體定時器是常用的工具,定時執行特定任務和延時功能,都可以用軟體定時器實作,
常見的延時函式的實作做法有:
1. 使用空指令進行延時,通過控制空指令的執行次數,進行延時,優點:不需要占用系統外設,缺點:系統運行指定個空指令的時間不穩定,中途出現的中斷處理會嚴重影響計時的精確性,
2.使用單片機的定時器外設,設定特定的時間產生中斷,進行計時,優點:計時準確,不受其他中斷影響計時,缺點:浪費單片機外設資源,并且延時處理不能嵌套呼叫,靈活性不夠,
這里要介紹的是利用單片機內部的sysTicket 定時器實作的軟體定時器,sysTicket timer每毫秒產生一次中斷,單片機內有一個無符號型別的32位全域變數msTicket對中斷次數進行計數,我們可以認為msTicket
為當前“系統時間”,
先介紹相對簡單的ms定時器,ms定時器的結構定義如下:
typedef struct
{
uint16_t start;
uint32_t value;
}MsSoftTimer;
start欄位用來表示定時器的開關狀態,考慮到位元組對齊的問題,用了十六位的型別,如果單片機存盤資源緊張,可以不用這個欄位,value欄位用來保存開始計時時刻系統的時間,也就是msTicket的值,
ms定時器的介面函式如下:
1 #define def_ms_tm(tm) MsSoftTimer tm;
2 #define declare_ms_tm(tm) extern MsSoftTimer tm;
3 #define get_ms_tm_val(tm) _get_ms_tm_val(tm.value)
4
5 #define start_ms_tm(tm) do \
6 { \
7 tm.start = 1; \
8 tm.value = get_msTicks(); \
9 }while(0)
10
11 #define init_ms_tm(tm) do \
12 { \
13 tm.start = 0; \
14 tm.value = 0; \
15 }while(0)
16
17 #define is_ms_tm_on(tm) ( tm.start)
18 #define stop_ms_tm(tm) tm.start = 0
定義定時器,本質是就是定義一個定時器型別的變數,可以嵌套呼叫,如果要在中斷處理函式中使用軟體定時器,要先將msTicket 中斷的優先級設定為最高級別的,并且可以搶占,獲取當前的計時時間,就是將當前的“系統時間”,減去定時器開始計時時刻的時間,具體實作如下:
1 uint32_t _get_ms_tm_val(uint32_t pre_timer_val)
2 {
3 uint32_t curr_timer_val = msTicks;
4 uint32_t ret_timer_val = 0;
5
6 if ( curr_timer_val >= pre_timer_val)
7 {
8 ret_timer_val = curr_timer_val - pre_timer_val;
9 }
10 else
11 {
12 ret_timer_val = 0xFFFFFFFF - pre_timer_val + curr_timer_val;
13 }
14
15 return ret_timer_val;
16 }
第12行代碼中,對msTicket 變數溢位做了判斷和處理,
利于ms軟體定時器實作的ms延時函式如下:
void delay_ms(uint32_t ms)
{
if ( ms == 0) return ;
def_ms_tm(tm_ms_count);
start_ms_tm(tm_ms_count);
while ( get_ms_tm_val(tm_ms_count) < ms)
;
stop_ms_tm(tm_ms_count);
}
us 定時器實作原理跟ms定時器類似,但會稍微復雜一些,us定時利用系統sysTicket 定時器內部的計數值(SysTick Current Value)進行計時,如果系統時鐘為20M,每隔1us,SysTick Current Value減少20,
如果系統時鐘為48M,每隔1us,SysTick Current Value 減少48,系統sysTicket 定時器結構如下:
1 typedef struct
2 {
3 __IO uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */
4 __IO uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */
5 __IO uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */
6 __I uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */
7 } SysTick_Type;
us 定時器的結構體如下:
1 typedef struct
2 {
3 uint16_t start;
4 uint32_t init_ticket_val;
5 uint32_t init_ms_val;
6 }UsSoftTimer;
init_ticket_val 記錄的是開始計時時刻SysTick Current Value的值,init_ms_val 記錄的是開始計時時刻msTicket 的值,
us 定時器介面函式實作如下:
1 void _start_us_sw(USSoftTimer* pTM)
2 {
3 pTM->init_ms_val = msTicks;
4 pTM->init_ticket_val = SysTick->VAL;
5 pTM->start = 1;
6 }
7
8 #pragma O0
9 uint32_t _get_us_tm_val(USSoftTimer* pTM)
10 {
11 volatile uint32_t curr_ms = msTicks;
12 volatile uint32_t curr_ticket_val = SysTick->VAL;
13 volatile uint32_t ms_interval = 0;
14 volatile uint32_t sys_clock = SysTick -> LOAD / 1000;
15 volatile uint32_t us_interval = 0;
16
17
18 if ( curr_ticket_val > pTM->init_ticket_val)
19 us_interval = ( SysTick->LOAD - (curr_ticket_val - pTM->init_ticket_val)) / sys_clock;
20 else
21 us_interval = (pTM->init_ticket_val - curr_ticket_val) / sys_clock;
22
23 if ( curr_ms != pTM->init_ms_val)
24 {
25
26 if ( curr_ms >= pTM->init_ms_val)
27 ms_interval = curr_ms - pTM->init_ms_val;
28 else
29 ms_interval = 0xFFFFFFFF - pTM->init_ms_val+ curr_ms;
30
31 if ( curr_ticket_val > pTM->init_ticket_val)
32 ms_interval -= 1;
33
34 us_interval += ms_interval * 1000;
35
36 }
37
38 return us_interval;
39 }
40
41 #define def_us_tm(tm) UsSoftTimer tm
42 #define declare_us_tm(tm) extern UsSoftTimer tm
43 #define get_us_tm_val(tm) _get_us_tm_val(&tm)
44 #define is_us_tm_on(tm) (1== tm.start)
45 #define stop_us_tm(tm) tm.start = 0
46 #define start_us_tm(tm) _start_us_sw(&tm)
us延時函式的實作如下:
1 void delay_us(uint32_t us)
2 {
3 if ( us <= 1) return ;
4 def_us_tm(tm_us_count);
5 start_us_tm(tm_us_count);
6 while ( get_us_tm_val(tm_us_count) < us)
7 ;
8 stop_us_tm(tm_us_count);
9 }
// END
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/385560.html
標籤:其他
