99国产精品欲av蜜臀,可以直接免费观看的AV网站,gogogo高清免费完整版,啊灬啊灬啊灬免费毛片

網易首頁 > 網易號 > 正文 申請入駐

編程經典案例:當線程遇到For循環,一個不可思議的Bug就出現了!

0
分享至

我們公司有個項目,需要視覺定位,大致就是在產品上會有一個“十字”形狀的Mark標記,然后通過視覺相機連續拍照,然后將拍到的圖片進行視覺算法運算,最終得出Mark標記的位置,然后根據其位置對設備進行位置糾正。但是,想不到就這么一個小功能卻出現了一個Bug,找了很久才發現原因!



說這個Bug之前,我需要先說下這個Bug是怎么被我寫出來的!說這個Bug之前,我需要先說下這個Bug是怎么被我寫出來的!

甲方那有一個設備,設備上有一個可以前后移動的軸,下稱M軸,軸上又裝了一個可以左右移動的軸,類似于貼片機的構造吧。我們用來視覺定位的相機就是裝在那個可以左右移動的軸上面的,下面簡稱P軸。

Mark標記處于P軸的初始位置,而且Mark的左右視野范圍被設定成不可超過P軸的初始位置,因此,要用Mark進行定位,只需要M軸前后移動,相機進行拍照即可,最后再根據Mark的位置調整P軸的位置。

最開始,我選擇的是一張一張得拍,并且我在封裝相機SDK的時候,取圖我只封裝了一個取單張圖片的接口。



后來發現算法速度跟不上M軸移動的速度,當相機拍了一張照片,然后程序再對照片進行視覺運算,中間會產生一定時間的間隙,當程序算完以后,M軸已經移動很遠了,拍到下一張圖片的時候,信息就會丟失一部分空間畫面。

如果Mark恰巧處于這個空間之內,那么很大概率就拍不到Mark標記了!

所以,我又在相機SDK里面重新封裝了一個接口,用來批量取圖,然后返回圖片地址列表,大致的邏輯就是根據視覺相機設置的幀率乘以M軸移動的總時間,換算出相機應該拍照的總照片數,假設相機幀率是10幀每秒,M軸總移動時間是3秒,那么應該取出的圖片就是10*3=30張。



這么做的目的就是在M軸移動的時候,純拍照片,然后將拍到的圖片保存在緩存目錄里面,其他什么都不做,這樣能讓視覺相機使用最大幀率去取圖,從而覆蓋M軸行程內的所有空間。最后,循環所有已經拍到的圖片,總有一張或者幾張圖片里面存在Mark標記!最后,再一次性返回所有圖片的保存地址。

雖然這個方案很好,但是在實際運行過程中卻出現了一個小的Bug,那就是Mark的檢測結果和實際展示圖片對不上!并且,還不是每次都會出現這樣的Bug,有時候就是好的。

癥狀就是,很多時候顯示的圖片里面明明沒有Mark標記,但是算法卻能識別出Mark標記來,或者有Mark標記,但是Mark標記被檢測出來的上下位置卻不一樣,可偏偏結果還是正確的!

最開始,我以為是算法有問題,后來這個問題很快被排除了。

那會不會是在循環圖片時,把圖片索引搞錯了呢?我仔細看了下我循環圖片,對圖片進行視覺運算的那段代碼,也沒發現問題。

本來,這個問題其實很好解決的,只要下個斷點調試一下就能發現問題出在哪,可偏偏軟件已經部署在了甲方那里,問題只能通過我們公司放在甲方那邊的同事跟我復述,我通過在代碼里面加運行日志來分析問題出現的原因。

因為日志總歸是人加的,它只能被加在我可能認為會出問題的地方,一些我不認為會出現問題的地方我是不會加的。

但偏偏有一個地方我就忽略了!

前面說了,我在視覺相機的SDK里面重新封裝了一個批量取圖的接口,而這個接口的邏輯是通過一個觸發拍照命令,輸入指定數量的圖片和取圖時間來取圖的,取出來的圖是放在一個指針數組里面的,我需要循環將指針轉換成圖片對象,然后再保存到緩存目錄里。

因為圖片數量太多,為了保證轉換效率,所以,我在循環指針數組的時候,使用了線程池來轉換圖片,問題就出在這!

我外層使用的是一個普通的循環,因為我不光要取圖,還需要保存圖片,而圖片名稱的某一個規則就是循環的當前索引,如“20250624_0_.jpg”,其中“_0_”中的0就是循環索引i的值。

因為使用的是線程池來執行取圖邏輯,那么在當前線程里面直接取i是有問題的!因為i的作用域是在循環內部,但是,循環內部如果執行的是一個線程,那么每一個線程所獲得到的i和這個線程的作用域不一樣,那么就會導致這個線程取到的i實際并不是順序的!

這么說不理解的話,我舉一個極端的例子:

假設我們需要拍30張圖片,這30張圖片被存在了一個指針數組里,我們通過For循環去循環指針數組,每循環一次,在線程池里面加一個線程,用來將指針轉換成圖片,而此時,我們PC的線程數已經被其他程序占用,因此,這30個線程都處于等待狀態,直到最后一次循環,此時i為30,循環完成后,此時前面被占用的線程瞬間被釋放,前面等待的這30個線程將全部執行,此時,這30個線程里面取到的所有i值將都是30!

而此時保存圖片,所有圖片名稱都是一樣的,因為圖片保存走的是覆蓋流程,最后程序執行下來,只會保存住一張圖片!

如果還不懂,請看示例:



這就是導致前面所有問題的根源!因為我在執行批量取圖之后,我需要重新循環圖片地址列表去讀取圖片,然后對圖片進行視覺運算以及顯示。

結合上面所說,如果最后30張圖片所有的i都是30的話,那么最終保存的圖片數量就只有一張了,此時,圖片數量就是1。



此時,我如果使用For循環這么寫:

For(int I = 0;i<1;i++)

這么一來,這個循環索引0所獲取到的圖片實際上是 “20250624_30_.jpg”,此時,如果視覺算法通過了,我會將圖片索引保存,此時保存的所謂的圖片索引就是0。



顯然,索引為0的圖片并不存在,因此,在圖片顯示的時候,這時候畫面上就只有Mark標記框,而沒有實際圖片。

那假設批量取圖數量是30,但是因為線程的原因,最終保存在文件夾里的圖片只有15張會出現什么結果呢?

很顯然,這時候循環索引和所有圖片的實際索引就都錯位了!

我也在批量取圖后的那個循環讀取圖片的For循環里面也加過日志,但是恰巧當時這個問題沒出現,我以為程序已經沒問題了,所以就將日志給去除了,后來再出問題時,就沒往這方面想了。

至于為什么不保存圖片地址而保存圖片循環的索引,這個是業務邏輯決定的。

當然,這么寫會出問題我是知道的,但是,您也知道,有時候寫代碼的事很難說,一個不注意寫出一個Bug其實很難發現的。

直到我查遍所有代碼,把所有可能性都一一排除以后,最后瞄了一眼我寫的相機SDK,一眼就發現了問題所在!

總結

在For循環中使用線程,并且在線程里面使用For循環的索引導致的錯誤,其實這是一個很經典的線程安全案例,我在過去接觸到的很多年輕的程序員在使用線程的時候基本上都會遇到這個問題。

如何避免這個問題呢?其實很簡單,就是強制將For循環的作用域限制到當層循環之內,寫法就是:



前后對比下,我只是將直接使用i的方式改成了先將i這個循環索引先賦值給變量index,然后再去使用,這樣,index這個變量的作用域就會被強制鎖定在當前循環內,不管最終線程什么時候執行,index的值不會變!

聲明:個人原創,僅供參考

特別聲明:以上內容(如有圖片或視頻亦包括在內)為自媒體平臺“網易號”用戶上傳并發布,本平臺僅提供信息存儲服務。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相關推薦
熱點推薦
商務部:何立峰將于7月27日至30日赴瑞典與美方舉行經貿會談

商務部:何立峰將于7月27日至30日赴瑞典與美方舉行經貿會談

新京報
2025-07-23 16:57:17
女星長澤雅美《Madame Figaro》雜志大片,利落短發優雅成熟大方

女星長澤雅美《Madame Figaro》雜志大片,利落短發優雅成熟大方

桃桃淘電影
2025-07-22 14:46:37
局勢升級!莫斯科又被襲擊,俄宣布退群,和歐洲國家態度徹底惡化

局勢升級!莫斯科又被襲擊,俄宣布退群,和歐洲國家態度徹底惡化

掌青說歷史
2025-07-22 17:08:55
商務部新聞發言人就中美瑞典經貿會談答記者問

商務部新聞發言人就中美瑞典經貿會談答記者問

界面新聞
2025-07-23 16:24:03
前法國國腳:我不喜歡亞馬爾為人處世的方式,他以為自己是美國人

前法國國腳:我不喜歡亞馬爾為人處世的方式,他以為自己是美國人

雷速體育
2025-07-23 17:47:43
湖南桂陽衛健局:4歲男童拔牙死亡涉事醫生停崗

湖南桂陽衛健局:4歲男童拔牙死亡涉事醫生停崗

界面新聞
2025-07-23 16:46:52
寶馬新款 X5 原型車內飾首曝:全景屏、17.9 英寸中控屏

寶馬新款 X5 原型車內飾首曝:全景屏、17.9 英寸中控屏

IT之家
2025-07-23 11:36:29
公職人員下班后兼職送三小時外賣:“像打游戲做任務”一樣快樂|封面頭條

公職人員下班后兼職送三小時外賣:“像打游戲做任務”一樣快樂|封面頭條

封面新聞
2025-07-22 15:48:22
你還是處女嗎?江西這95后姑娘相親,就被年薪百萬的IT男問懵了…

你還是處女嗎?江西這95后姑娘相親,就被年薪百萬的IT男問懵了…

火山詩話
2025-07-21 19:50:24
堅持埼玉的訓練方法1000天之后,堂主lee成為了真正的一拳超人

堅持埼玉的訓練方法1000天之后,堂主lee成為了真正的一拳超人

手談姬
2025-07-22 20:56:03
杜賓犬撲童最新:狗主人登門道歉,身份被扒不差錢,知情人曝內幕

杜賓犬撲童最新:狗主人登門道歉,身份被扒不差錢,知情人曝內幕

悠閑歷史
2025-07-22 17:40:24
錯付車費輕生后續,哥哥曝案發細節,司機身份泄露,警方惹爭議

錯付車費輕生后續,哥哥曝案發細節,司機身份泄露,警方惹爭議

一家說
2025-07-23 09:42:03
“絕經和出道同時來?”上海街頭驚現她的巨幅海報!網友:笑著笑著就哭了

“絕經和出道同時來?”上海街頭驚現她的巨幅海報!網友:笑著笑著就哭了

環球網資訊
2025-07-23 10:48:19
雅魯藏布江水電工程僅離中印實控線18公里,中國不怕印度襲擊?

雅魯藏布江水電工程僅離中印實控線18公里,中國不怕印度襲擊?

大道無形我有型
2025-07-23 13:31:24
2025養老金調整迎來最新消息,及時發放下,企退事退補發相差多少

2025養老金調整迎來最新消息,及時發放下,企退事退補發相差多少

興史興談
2025-07-23 14:48:04
僅大16歲,老少戀的“殘酷”,為何在63歲馬蘭身上體現得淋漓盡致

僅大16歲,老少戀的“殘酷”,為何在63歲馬蘭身上體現得淋漓盡致

山河月明史
2025-07-23 14:19:48
菲律賓跪了!馬尼拉時報:我們完蛋了,特朗普抓住了馬科斯的把柄

菲律賓跪了!馬尼拉時報:我們完蛋了,特朗普抓住了馬科斯的把柄

掌青說歷史
2025-07-23 17:19:18
14年前我借給鄰居75萬,他全家搬走,昨天收到遺產繼承書我傻眼了

14年前我借給鄰居75萬,他全家搬走,昨天收到遺產繼承書我傻眼了

今天說故事
2025-07-19 10:57:50
墨脫縣的4/5控制在印度人手中,必須建個超級水電站重塑地緣格局

墨脫縣的4/5控制在印度人手中,必須建個超級水電站重塑地緣格局

大道無形我有型
2025-07-23 11:30:09
朱小杰任同濟大學黨委常務副書記,曾在教育部任職

朱小杰任同濟大學黨委常務副書記,曾在教育部任職

澎湃新聞
2025-07-23 16:52:27
2025-07-23 20:15:00
程序員古耕 incentive-icons
程序員古耕
程序員、網文作家、自媒體人
555文章數 371關注度
往期回顧 全部

科技要聞

別自嗨了!XREAL徐馳:AI眼鏡只有5歲智商

頭條要聞

印度、孟加拉關切雅魯藏布江下游水電站工程 中方回應

頭條要聞

印度、孟加拉關切雅魯藏布江下游水電站工程 中方回應

體育要聞

英格蘭最紅球星 也是加勒比島國驕傲

娛樂要聞

汪峰森林北同游日本 各帶各娃互不耽誤

財經要聞

律師解析娃哈哈遺產案:遺囑是最大變數

汽車要聞

德系大招放盡 場地極限測試全新奧迪A5L

態度原創

房產
教育
數碼
親子
時尚

房產要聞

海南自由貿易港全島封關,2025年12月18日正式啟動!

教育要聞

2025年天津高考提前批投檔線分析:中國民航大學訂單班受熱捧

數碼要聞

全漢帶來 VIC GD 系列電源:僅擁有 3 年質保的金牌非模組 ATX

親子要聞

新年吃什么爸爸說交給孩子們自己決定,又是有趣的一餐

看來看去還是這些穿搭適合普通人!配色不艷、衣服不花,好得體

無障礙瀏覽 進入關懷版 主站蜘蛛池模板: 黎平县| 麦盖提县| 华安县| 南部县| 印江| 广昌县| 蒙自县| 寻乌县| 祁东县| 马尔康县| 新和县| 盘锦市| 宁陵县| 武穴市| 汤阴县| 新郑市| 济宁市| 河南省| 庆安县| 乡宁县| 神池县| 彰化县| 屏南县| 普兰店市| 乐都县| 泸水县| 永福县| 枣阳市| 莱阳市| 磴口县| 梅州市| 获嘉县| 竹北市| 陆丰市| 宝坻区| 平塘县| 雅安市| 桂东县| 常德市| 察隅县| 盘山县|