国产av一二三区|日本不卡动作网站|黄色天天久久影片|99草成人免费在线视频|AV三级片成人电影在线|成年人aV不卡免费播放|日韩无码成人一级片视频|人人看人人玩开心色AV|人妻系列在线观看|亚洲av无码一区二区三区在线播放

網(wǎng)易首頁(yè) > 網(wǎng)易號(hào) > 正文 申請(qǐng)入駐

編程經(jīng)典案例:當(dāng)線程遇到For循環(huán),一個(gè)不可思議的Bug就出現(xiàn)了!

0
分享至

我們公司有個(gè)項(xiàng)目,需要視覺(jué)定位,大致就是在產(chǎn)品上會(huì)有一個(gè)“十字”形狀的Mark標(biāo)記,然后通過(guò)視覺(jué)相機(jī)連續(xù)拍照,然后將拍到的圖片進(jìn)行視覺(jué)算法運(yùn)算,最終得出Mark標(biāo)記的位置,然后根據(jù)其位置對(duì)設(shè)備進(jìn)行位置糾正。但是,想不到就這么一個(gè)小功能卻出現(xiàn)了一個(gè)Bug,找了很久才發(fā)現(xiàn)原因!

說(shuō)這個(gè)Bug之前,我需要先說(shuō)下這個(gè)Bug是怎么被我寫(xiě)出來(lái)的!說(shuō)這個(gè)Bug之前,我需要先說(shuō)下這個(gè)Bug是怎么被我寫(xiě)出來(lái)的!

甲方那有一個(gè)設(shè)備,設(shè)備上有一個(gè)可以前后移動(dòng)的軸,下稱M軸,軸上又裝了一個(gè)可以左右移動(dòng)的軸,類(lèi)似于貼片機(jī)的構(gòu)造吧。我們用來(lái)視覺(jué)定位的相機(jī)就是裝在那個(gè)可以左右移動(dòng)的軸上面的,下面簡(jiǎn)稱P軸。

Mark標(biāo)記處于P軸的初始位置,而且Mark的左右視野范圍被設(shè)定成不可超過(guò)P軸的初始位置,因此,要用Mark進(jìn)行定位,只需要M軸前后移動(dòng),相機(jī)進(jìn)行拍照即可,最后再根據(jù)Mark的位置調(diào)整P軸的位置。

最開(kāi)始,我選擇的是一張一張得拍,并且我在封裝相機(jī)SDK的時(shí)候,取圖我只封裝了一個(gè)取單張圖片的接口。

后來(lái)發(fā)現(xiàn)算法速度跟不上M軸移動(dòng)的速度,當(dāng)相機(jī)拍了一張照片,然后程序再對(duì)照片進(jìn)行視覺(jué)運(yùn)算,中間會(huì)產(chǎn)生一定時(shí)間的間隙,當(dāng)程序算完以后,M軸已經(jīng)移動(dòng)很遠(yuǎn)了,拍到下一張圖片的時(shí)候,信息就會(huì)丟失一部分空間畫(huà)面。

如果Mark恰巧處于這個(gè)空間之內(nèi),那么很大概率就拍不到Mark標(biāo)記了!

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

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

雖然這個(gè)方案很好,但是在實(shí)際運(yùn)行過(guò)程中卻出現(xiàn)了一個(gè)小的Bug,那就是Mark的檢測(cè)結(jié)果和實(shí)際展示圖片對(duì)不上!并且,還不是每次都會(huì)出現(xiàn)這樣的Bug,有時(shí)候就是好的。

癥狀就是,很多時(shí)候顯示的圖片里面明明沒(méi)有Mark標(biāo)記,但是算法卻能識(shí)別出Mark標(biāo)記來(lái),或者有Mark標(biāo)記,但是Mark標(biāo)記被檢測(cè)出來(lái)的上下位置卻不一樣,可偏偏結(jié)果還是正確的!

最開(kāi)始,我以為是算法有問(wèn)題,后來(lái)這個(gè)問(wèn)題很快被排除了。

那會(huì)不會(huì)是在循環(huán)圖片時(shí),把圖片索引搞錯(cuò)了呢?我仔細(xì)看了下我循環(huán)圖片,對(duì)圖片進(jìn)行視覺(jué)運(yùn)算的那段代碼,也沒(méi)發(fā)現(xiàn)問(wèn)題。

本來(lái),這個(gè)問(wèn)題其實(shí)很好解決的,只要下個(gè)斷點(diǎn)調(diào)試一下就能發(fā)現(xiàn)問(wèn)題出在哪,可偏偏軟件已經(jīng)部署在了甲方那里,問(wèn)題只能通過(guò)我們公司放在甲方那邊的同事跟我復(fù)述,我通過(guò)在代碼里面加運(yùn)行日志來(lái)分析問(wèn)題出現(xiàn)的原因。

因?yàn)槿罩究倸w是人加的,它只能被加在我可能認(rèn)為會(huì)出問(wèn)題的地方,一些我不認(rèn)為會(huì)出現(xiàn)問(wèn)題的地方我是不會(huì)加的。

但偏偏有一個(gè)地方我就忽略了!

前面說(shuō)了,我在視覺(jué)相機(jī)的SDK里面重新封裝了一個(gè)批量取圖的接口,而這個(gè)接口的邏輯是通過(guò)一個(gè)觸發(fā)拍照命令,輸入指定數(shù)量的圖片和取圖時(shí)間來(lái)取圖的,取出來(lái)的圖是放在一個(gè)指針數(shù)組里面的,我需要循環(huán)將指針轉(zhuǎn)換成圖片對(duì)象,然后再保存到緩存目錄里。

因?yàn)閳D片數(shù)量太多,為了保證轉(zhuǎn)換效率,所以,我在循環(huán)指針數(shù)組的時(shí)候,使用了線程池來(lái)轉(zhuǎn)換圖片,問(wèn)題就出在這!

我外層使用的是一個(gè)普通的循環(huán),因?yàn)槲也还庖D,還需要保存圖片,而圖片名稱的某一個(gè)規(guī)則就是循環(huán)的當(dāng)前索引,如“20250624_0_.jpg”,其中“_0_”中的0就是循環(huán)索引i的值。

因?yàn)槭褂玫氖蔷€程池來(lái)執(zhí)行取圖邏輯,那么在當(dāng)前線程里面直接取i是有問(wèn)題的!因?yàn)閕的作用域是在循環(huán)內(nèi)部,但是,循環(huán)內(nèi)部如果執(zhí)行的是一個(gè)線程,那么每一個(gè)線程所獲得到的i和這個(gè)線程的作用域不一樣,那么就會(huì)導(dǎo)致這個(gè)線程取到的i實(shí)際并不是順序的!

這么說(shuō)不理解的話,我舉一個(gè)極端的例子:

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

而此時(shí)保存圖片,所有圖片名稱都是一樣的,因?yàn)閳D片保存走的是覆蓋流程,最后程序執(zhí)行下來(lái),只會(huì)保存住一張圖片!

如果還不懂,請(qǐng)看示例:

這就是導(dǎo)致前面所有問(wèn)題的根源!因?yàn)槲以趫?zhí)行批量取圖之后,我需要重新循環(huán)圖片地址列表去讀取圖片,然后對(duì)圖片進(jìn)行視覺(jué)運(yùn)算以及顯示。

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

此時(shí),我如果使用For循環(huán)這么寫(xiě):

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

這么一來(lái),這個(gè)循環(huán)索引0所獲取到的圖片實(shí)際上是 “20250624_30_.jpg”,此時(shí),如果視覺(jué)算法通過(guò)了,我會(huì)將圖片索引保存,此時(shí)保存的所謂的圖片索引就是0。

顯然,索引為0的圖片并不存在,因此,在圖片顯示的時(shí)候,這時(shí)候畫(huà)面上就只有Mark標(biāo)記框,而沒(méi)有實(shí)際圖片。

那假設(shè)批量取圖數(shù)量是30,但是因?yàn)榫€程的原因,最終保存在文件夾里的圖片只有15張會(huì)出現(xiàn)什么結(jié)果呢?

很顯然,這時(shí)候循環(huán)索引和所有圖片的實(shí)際索引就都錯(cuò)位了!

我也在批量取圖后的那個(gè)循環(huán)讀取圖片的For循環(huán)里面也加過(guò)日志,但是恰巧當(dāng)時(shí)這個(gè)問(wèn)題沒(méi)出現(xiàn),我以為程序已經(jīng)沒(méi)問(wèn)題了,所以就將日志給去除了,后來(lái)再出問(wèn)題時(shí),就沒(méi)往這方面想了。

至于為什么不保存圖片地址而保存圖片循環(huán)的索引,這個(gè)是業(yè)務(wù)邏輯決定的。

當(dāng)然,這么寫(xiě)會(huì)出問(wèn)題我是知道的,但是,您也知道,有時(shí)候?qū)懘a的事很難說(shuō),一個(gè)不注意寫(xiě)出一個(gè)Bug其實(shí)很難發(fā)現(xiàn)的。

直到我查遍所有代碼,把所有可能性都一一排除以后,最后瞄了一眼我寫(xiě)的相機(jī)SDK,一眼就發(fā)現(xiàn)了問(wèn)題所在!

總結(jié)

在For循環(huán)中使用線程,并且在線程里面使用For循環(huán)的索引導(dǎo)致的錯(cuò)誤,其實(shí)這是一個(gè)很經(jīng)典的線程安全案例,我在過(guò)去接觸到的很多年輕的程序員在使用線程的時(shí)候基本上都會(huì)遇到這個(gè)問(wèn)題。

如何避免這個(gè)問(wèn)題呢?其實(shí)很簡(jiǎn)單,就是強(qiáng)制將For循環(huán)的作用域限制到當(dāng)層循環(huán)之內(nèi),寫(xiě)法就是:

前后對(duì)比下,我只是將直接使用i的方式改成了先將i這個(gè)循環(huán)索引先賦值給變量index,然后再去使用,這樣,index這個(gè)變量的作用域就會(huì)被強(qiáng)制鎖定在當(dāng)前循環(huán)內(nèi),不管最終線程什么時(shí)候執(zhí)行,index的值不會(huì)變!

聲明:個(gè)人原創(chuàng),僅供參考

特別聲明:以上內(nèi)容(如有圖片或視頻亦包括在內(nèi))為自媒體平臺(tái)“網(wǎng)易號(hào)”用戶上傳并發(fā)布,本平臺(tái)僅提供信息存儲(chǔ)服務(wù)。

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.

相關(guān)推薦
熱點(diǎn)推薦
退休后你會(huì)到鄉(xiāng)下養(yǎng)老嗎?網(wǎng)友:鄉(xiāng)下沒(méi)這么嚇人

退休后你會(huì)到鄉(xiāng)下養(yǎng)老嗎?網(wǎng)友:鄉(xiāng)下沒(méi)這么嚇人

帶你感受人間冷暖
2026-02-23 00:49:19
網(wǎng)飛特離譜的黃暴美劇,偏偏還很火,真是獨(dú)一份了

網(wǎng)飛特離譜的黃暴美劇,偏偏還很火,真是獨(dú)一份了

來(lái)看美劇
2026-02-01 19:51:56
方媛曬3胎女兒滿月禮!金鎖玉鐲多到放不下,3500的嬰兒車(chē)不算貴

方媛曬3胎女兒滿月禮!金鎖玉鐲多到放不下,3500的嬰兒車(chē)不算貴

小娛樂(lè)悠悠
2026-02-28 11:02:55
危險(xiǎn)信號(hào)!賴清德大勝,綠營(yíng)變天,鄭麗文突然改口:支持對(duì)美軍購(gòu)

危險(xiǎn)信號(hào)!賴清德大勝,綠營(yíng)變天,鄭麗文突然改口:支持對(duì)美軍購(gòu)

Ck的蜜糖
2026-02-25 15:08:12
不是那個(gè)年代的,你真看不懂

不是那個(gè)年代的,你真看不懂

深度報(bào)
2026-02-15 23:01:53
臺(tái)積電前高管評(píng)價(jià)中國(guó)芯片:東西做的不好,但關(guān)鍵時(shí)期能拿出來(lái)用

臺(tái)積電前高管評(píng)價(jià)中國(guó)芯片:東西做的不好,但關(guān)鍵時(shí)期能拿出來(lái)用

星星會(huì)墜落
2026-02-26 20:53:30
知人知面不知心!回國(guó)就原形畢露!孫穎莎樊振東:緊急取關(guān)!

知人知面不知心!回國(guó)就原形畢露!孫穎莎樊振東:緊急取關(guān)!

海闊山遙YAO
2026-03-01 03:20:53
沖突爆發(fā)!下周就看這3個(gè)!

沖突爆發(fā)!下周就看這3個(gè)!

風(fēng)風(fēng)順
2026-03-01 04:15:03
美國(guó)終于怕了,比稀土更致命的王牌,終于出手了!萬(wàn)斯:中國(guó)要冷靜

美國(guó)終于怕了,比稀土更致命的王牌,終于出手了!萬(wàn)斯:中國(guó)要冷靜

青煙小先生
2026-02-28 09:24:04
億萬(wàn)國(guó)人破防!90歲院士平靜宣布,中國(guó)導(dǎo)彈從此沒(méi)有任何死角!

億萬(wàn)國(guó)人破防!90歲院士平靜宣布,中國(guó)導(dǎo)彈從此沒(méi)有任何死角!

墨印齋
2026-02-28 16:54:29
陽(yáng)光城集團(tuán)創(chuàng)始人林騰蛟滯留香港

陽(yáng)光城集團(tuán)創(chuàng)始人林騰蛟滯留香港

地產(chǎn)微資訊
2026-02-28 16:28:21
美國(guó)軍力全球第一,敢打任何國(guó)家?俄潑冷水:這4國(guó)你敢打誰(shuí)?

美國(guó)軍力全球第一,敢打任何國(guó)家?俄潑冷水:這4國(guó)你敢打誰(shuí)?

近史談
2026-01-19 10:09:51
2025年山東縣級(jí)市GDP十強(qiáng)表現(xiàn),龍口遙遙領(lǐng)先,平度突破千億

2025年山東縣級(jí)市GDP十強(qiáng)表現(xiàn),龍口遙遙領(lǐng)先,平度突破千億

王二哥老搞笑
2026-02-28 20:35:34
研究警告:越來(lái)越多家庭因吃它中毒!冰箱里這類(lèi)肉別超3個(gè)月!

研究警告:越來(lái)越多家庭因吃它中毒!冰箱里這類(lèi)肉別超3個(gè)月!

全球軍事記
2026-02-28 10:12:38
體制內(nèi)有以下副業(yè),紀(jì)委不會(huì)查!

體制內(nèi)有以下副業(yè),紀(jì)委不會(huì)查!

微法官
2026-02-23 08:24:43
4500億華潤(rùn)銀行正式更名

4500億華潤(rùn)銀行正式更名

21世紀(jì)經(jīng)濟(jì)報(bào)道
2026-02-28 15:18:07
糟糕!五糧液董事長(zhǎng)被抓了,年薪不到70萬(wàn)啊

糟糕!五糧液董事長(zhǎng)被抓了,年薪不到70萬(wàn)啊

說(shuō)財(cái)貓
2026-03-01 00:04:17
此隧道一旦建成,將打破青島交通死角格局,使其成為東北亞樞紐?

此隧道一旦建成,將打破青島交通死角格局,使其成為東北亞樞紐?

好笑娛樂(lè)君每一天
2026-02-28 11:46:51
轉(zhuǎn)發(fā)提醒!在伊朗的中國(guó)公民盡快撤離

轉(zhuǎn)發(fā)提醒!在伊朗的中國(guó)公民盡快撤離

閃電新聞
2026-02-27 19:30:43
“情人”的圈套!1981年長(zhǎng)沙市“4·30”西郊無(wú)名女尸案?jìng)善剖寄?>
    </a>
        <h3>
      <a href=路之意
2026-02-27 16:14:54
2026-03-01 06:00:49
程序員古耕 incentive-icons
程序員古耕
程序員、網(wǎng)文作家、自媒體人
599文章數(shù) 389關(guān)注度
往期回顧 全部

科技要聞

狂攬1100億美元!OpenAI再創(chuàng)融資神話

頭條要聞

以官員稱哈梅內(nèi)伊身亡 遺體在其官邸廢墟中被找到

頭條要聞

以官員稱哈梅內(nèi)伊身亡 遺體在其官邸廢墟中被找到

體育要聞

球隊(duì)主力全報(bào)銷(xiāo)?頂風(fēng)擺爛演都不演了

娛樂(lè)要聞

周杰倫兒子正面照曝光,與父親好像

財(cái)經(jīng)要聞

沖突爆發(fā) 市場(chǎng)變天?

汽車(chē)要聞

嵐圖泰山黑武士版3月上市 搭載華為四激光智駕方案

態(tài)度原創(chuàng)

本地
健康
教育
手機(jī)
旅游

本地新聞

津南好·四時(shí)總相宜

轉(zhuǎn)頭就暈的耳石癥,能開(kāi)車(chē)上班嗎?

教育要聞

又看了一遍…覺(jué)得這冊(cè)子真的太牛了…

手機(jī)要聞

澎湃OS再次公布進(jìn)展通報(bào):10個(gè)問(wèn)題,僅修復(fù)一則!

旅游要聞

3大亮點(diǎn)!石柱黎場(chǎng)油菜花,承包整個(gè)春天的浪漫

無(wú)障礙瀏覽 進(jìn)入關(guān)懷版