串列埠除錯心得:竟然是for迴圈惹的禍
阿新 • • 發佈:2019-02-19
在用COM口連線機器時,傳送簡單的命令和小檔案都很OK的,可是在傳送一個較大的檔案時,出現了問題。
後面開COM口除錯工具PORTMON進行跟蹤,發現是機器回饋到COM口的資料包不正確,致使分析這個資料包時,得出了錯誤的結論,認為檔案傳送失敗了。
於是開始思考是什麼造成的?經過分析,問題鎖定在檔案的切包傳送上(為了方便,直接用了for迴圈來發送檔案的切包),難道是傳送的太快,造成下端機器無法快速處理?於是在發包的迴圈中加入了sleep。可是sleep一直提升到了3秒依然沒有作用,所以漸漸覺得問題可能不是在這邊。
這時,想到COM口操作其實在根本上是檔案操作(看COM口的API就可以知道),所以如果說回饋的資料包不正確,有可能是COM口對應的檔案出了問題。但是仔細一想,又不太可能,因為這是系統級的,不可能這麼輕易的就出了問題。
又想了很久,最後想著,要不就不用for迴圈,另外開個執行緒來發送。果斷用執行緒傳送,結果真的就成功了。不但發的OK,收的也OK。於是反過來想,執行緒操作是為了時間片更好的分配,而剛剛的for迴圈裡也用了sleep來讓主執行緒去分配時間片,為什麼會不行?
再看看程式碼,原來for是在主執行緒中,而for是序列執行的,所以即便sleep了,也是讓主執行緒sleep,並沒有起取真正分配時間片的目的,而執行緒卻的sleep是真正的騰出了時間片讓主執行緒去分配。
同時,由於for的序列執行,使得資料會持續的送往下端,而負責抓取COM口回饋的執行緒沒時間去抓取。
後面開COM口除錯工具PORTMON進行跟蹤,發現是機器回饋到COM口的資料包不正確,致使分析這個資料包時,得出了錯誤的結論,認為檔案傳送失敗了。
於是開始思考是什麼造成的?經過分析,問題鎖定在檔案的切包傳送上(為了方便,直接用了for迴圈來發送檔案的切包),難道是傳送的太快,造成下端機器無法快速處理?於是在發包的迴圈中加入了sleep。可是sleep一直提升到了3秒依然沒有作用,所以漸漸覺得問題可能不是在這邊。
這時,想到COM口操作其實在根本上是檔案操作(看COM口的API就可以知道),所以如果說回饋的資料包不正確,有可能是COM口對應的檔案出了問題。但是仔細一想,又不太可能,因為這是系統級的,不可能這麼輕易的就出了問題。
又想了很久,最後想著,要不就不用for迴圈,另外開個執行緒來發送。果斷用執行緒傳送,結果真的就成功了。不但發的OK,收的也OK。於是反過來想,執行緒操作是為了時間片更好的分配,而剛剛的for迴圈裡也用了sleep來讓主執行緒去分配時間片,為什麼會不行?
再看看程式碼,原來for是在主執行緒中,而for是序列執行的,所以即便sleep了,也是讓主執行緒sleep,並沒有起取真正分配時間片的目的,而執行緒卻的sleep是真正的騰出了時間片讓主執行緒去分配。
同時,由於for的序列執行,使得資料會持續的送往下端,而負責抓取COM口回饋的執行緒沒時間去抓取。