微控制器實現環形佇列 如何快速實現「延時訊息」?

2021-10-13 20:39:45 字數 2070 閱讀 3822

快狗打車訂單完成後,如果使用者一直不評價,48小時後會將自動評價為5星。

怎麼實現這類「48小時後自動評價為5星」需求呢?

畫外音:這類「一段時間之後,完成乙個任務」的需求很常見。

cron是不是最容易想到的方案?

啟動乙個cron定時任務,每小時跑一次,將完成時間超過48小時,且仍未評價的訂單取出,置為5星,並把評價狀態置為已評價。

假設訂單表的結構為:

order(oid, finish_time, stars, status, …)

更具體的,定時任務每隔乙個小時會這麼做一次:

select oid from order where finish_time > 48 and status=0;

update order set stars=5 and status=1 where oid in[…];

如果資料量很大,需要分頁查詢,分頁update,這將會是乙個for迴圈。

cron方案有什麼不足?

(1)輪詢效率比較低;

(2)每次掃庫,已經被執行過記錄,仍然會被掃瞄(只是不會出現在結果集中),有重複計算的嫌疑;

(3)時效性不夠好,如果每小時輪詢一次,最差的情況下,時間誤差會達到1小時;

(4)如果通過增加cron輪詢頻率來減少時間誤差,則輪詢低效和重複計算的問題會進一步凸顯;

對於這類需要延時執行的任務,如何保證效率的同時,又保證實時性呢?

答案是:高效延時訊息。

高效延時訊息,包含兩個重要的資料結構

(1)環形佇列,例如可以建立乙個包含3600個slot的環形佇列(本質是個陣列);

(2)任務集合,環上每乙個slot是乙個set

同時,啟動乙個timer

(1)此timer每隔1s,在環形佇列中移動一格;

(2)用乙個current index來標識正在檢測的slot;

task結構中有兩個很重要的屬性

(1)cycle-num:當current index第幾圈掃瞄到這個slot時,執行任務;

(2)task-function:需要執行的任務函式;

如上圖,假設當前current index指向第一格,當有延時訊息到達之後,例如希望3610秒之後,觸發乙個延時訊息任務,只需:

(1)計算這個task應該放在哪乙個slot,現在指向1,3610秒之後,應該是第11格,所以這個task應該放在第11個slot的set中;

(2)計算這個task的cycle-num,由於環形佇列是3600格(每秒移動一格,正好1小時),這個任務是3610秒後執行,所以應該繞3610/3600=1圈之後再執行,於是cycle-num=1;

current index不停的移動,每秒移動一格,當移動到乙個新slot,遍歷這個slot中對應的set,每個task看cycle-num是不是0:

(1)如果不是0,說明還需要多移動幾圈,將cycle-num減1;

(2)如果是0,說明馬上要執行這個task了,取出task-funciton執行,丟給工作執行緒執行,並把這個task從set中刪除;

畫外音:注意,不要用timer來執行任務,否則timer會越來越不准。

使用了「延時訊息」方案之後,「訂單48小時後關閉評價」的需求,只需將在訂單關閉時,觸發乙個48小時之後的延時訊息即可:

(1)無需再輪詢全部訂單,效率高

(2)乙個訂單,任務只執行一次

(3)時效性好,精確到秒;

畫外音:控制timer移動頻率可以控制精度。

微控制器實現軟體濾波

1 限幅濾波法 又稱程式判斷濾波法 a 方法 根據經驗判斷,確定兩次取樣允許的最大偏差值 設為a 每次檢測到新值時判斷 如果本次值與上次值之差 a,則本次值有效 如果本次值與上次值之差 a,則本次值無效,放棄本次值,用上次值代替本次值 b 優點 能有效克服因偶然因素引起的脈衝干擾 c 缺點 無法抑制...

微控制器流星燈 51微控制器拖尾燈實現

這個拖尾燈,或者掃瞄燈,或者流星燈,不管怎麼叫,原理上估計都是一樣的。這玩意困擾了我好長的時間。我知道用pwm可以做出明暗效果。但是無法做到實現多路控制。在網上有種叫 霹靂遊俠掃瞄燈 的東西。好像是用專用的ic做的。找不到相關的原始碼。自己想啊想。一直想了乙個月。直到昨天,上課的時候靈光一閃,突然想...

微控制器藍芽燒錄 用微控制器實現藍芽功能

下面的文字只是關於藍芽技術的調製演算法方面,我認為只需要將藍芽模組加 在微控制器上就可以了,而不必通過微控制器程式設計來實現具體的演算法,只需要編 寫使兩個模組的介面就可以,也就是微控制器傳送訊號時的激勵程式,接受外 來訊號後的處理程式。置於其餘就由作為硬體裝置的藍芽來自行處理。不過 我並不確定,我...