LABVIEW的深入探索之全局變量的優(yōu)劣
sandan0615:
本文引用地址:http://m.butianyuan.cn/article/201701/337245.htm在保證數(shù)據(jù)不沖突的情況下可以對(duì)全局變量寫操作嗎?
RTRT,各位高手解釋下,我在陳樹學(xué)老師的寶典里看到說在程序里要避免對(duì)全局變量進(jìn)行寫操作。
czhen:
當(dāng)然可以
不行的話,要它干啥
wyb4993:
我有一個(gè)自動(dòng)化測(cè)試程序,里面有很多LabVIEW全局變量,可以讀和寫。是前一任離職的兄弟留下的。目前運(yùn)行很正常。
關(guān)于慎用全局變量的問題,很多編程語言方面的書籍都會(huì)提及,NI論壇上有一個(gè)長達(dá)十幾頁的帖子專門討論的這個(gè)問題,非常詳細(xì)。
其中不僅僅涉及全局變量,還提及了許多解決問題的技巧。
下面我大概翻譯一下其中重要的部分,希望有助于理解如何正確使用全局變量。帖子很長,我需要用幾天的時(shí)間陸續(xù)給大家介紹。
-------------------------------------------------------------------------------------------------------------------------------
TBOB:
不止一次地看到人們?cè)诒г梗肿兞渴亲飷褐?,根本就不?yīng)該使用它們。但是我不認(rèn)為這個(gè)結(jié)論是顯而易見正確的。我希望能聽到一次有關(guān)全局變量的嚴(yán)肅認(rèn)真的討論。論壇中的朋友們很多都提到了他們都正在編程中使用全局變量。
先從全局變量的有點(diǎn)談起。一般來說,全局變量是公認(rèn)的在各個(gè)VI之間傳遞數(shù)據(jù)的有效方法,比起其它方式的全局變量(個(gè)人意見)更容易管理,因?yàn)榧偃缥覀兪褂昧艘粋€(gè)簇作為全局?jǐn)?shù)據(jù),我們沒有辦法確定在何處使用了它們,可能需要自己創(chuàng)建一個(gè)文件記錄它們使用的位置。但是全局變量則不然,通過全局變量的右鍵快捷菜單,我們可以很容找到引用全局變量的位置。
使用全局變量有兩個(gè)不利之處,其一,引用全局變量需要?jiǎng)?chuàng)建數(shù)據(jù)的拷貝,這可能會(huì)導(dǎo)致潛在的競爭條件或者導(dǎo)致數(shù)據(jù)的丟失。其二,使用全局變量會(huì)中斷數(shù)據(jù)流程。
所以,我對(duì)那些反對(duì)使用全局變量的人士提出一個(gè)問題---你們?cè)趹?yīng)用全局變量時(shí)考慮了全局變量是否有效的問題了嗎?
如果對(duì)全局變量只有一個(gè)寫入者,而有多處讀取者,您僅僅關(guān)心變量的最新寫入值的情況下,您怎么能斷定不能使用全局變量呢?
---------------------------------------------------------------------------------------------------------------------------
Darren:
全局變量在某些情況下是非常好用的。如果我有一些靜態(tài)數(shù)據(jù),這些靜態(tài)數(shù)據(jù)必須在多個(gè)VI中共享,這種情況下,我會(huì)使用全局變量存儲(chǔ)這些靜態(tài)數(shù)據(jù)。(所謂靜態(tài)數(shù)據(jù)就是不需要改變的數(shù)據(jù),常量)。最常見的例子是需要給用戶提示的文本字符串。如果我有一個(gè)非常復(fù)雜的GUI,需要在很多地方向用戶提示文本信息。我會(huì)創(chuàng)建一個(gè)全局變量VI,把這些字符串創(chuàng)建為全局變量,并且按照字母順序排序(通過設(shè)置TAB ORDER)。這樣我們需要在程序框圖中使用全局變量時(shí),直接拖入并選擇我們需要的。這種方法可以很容易使我們的應(yīng)用程序本地化,因?yàn)樗械娘@示字符串集中在一個(gè)VI之中,而不是散布在各個(gè)VI之中,很容易集中處理。
我另外一次使用全局變量是在一個(gè)子面板應(yīng)用中,因?yàn)槲业淖用姘逯械腣I不需要和主VI交換信息,所以我將子面板VI中的數(shù)據(jù)寫入全局變量,供應(yīng)用程序其它部分讀取。因?yàn)椴恍枰交约爸挥凶用姘逯械腣I寫入數(shù)據(jù),保證了只有一個(gè)寫入者,這恰恰是全局變量的最佳工作方式。
--------------------------------------------------------------------------------------------------------------------
TBOB:
很高興能看到同人談及如何恰當(dāng)?shù)厥褂萌肿兞?,而不是簡單地說完全不要使用全局變量。我們更應(yīng)該強(qiáng)調(diào)如何恰當(dāng)?shù)厥褂萌肿兞?,幫助人們了解?shù)據(jù)競爭是如何產(chǎn)生的,以及如何避免競爭情況出現(xiàn)。
我大多數(shù)使用全局變量時(shí),是把全局變量作為常量來使用的,比如保存一個(gè)GPIB的地址。它們一旦創(chuàng)建后就永遠(yuǎn)不會(huì)再次寫入更改,這種情況下,絕對(duì)不會(huì)出現(xiàn)數(shù)據(jù)競爭的情況。或者在生產(chǎn)消費(fèi)者模式中,生產(chǎn)者寫入全局變量,而消費(fèi)者讀取全局變量。這種情況下,讀的時(shí)機(jī)是非常重要的。我使消費(fèi)者不斷查詢?nèi)肿兞?,是否和原來的值發(fā)生變化。換句話說,消費(fèi)者在數(shù)據(jù)更新之前可能讀取了兩次,當(dāng)然并不很理想。
對(duì)于局部變量也是如此,總有它們合適使用的場(chǎng)合,但是必須小心可能會(huì)導(dǎo)致的問題。教會(huì)人們發(fā)現(xiàn)問題和解決問題好于僅僅說避免使用它們。
--------------------------------------------------------------------------------------------------------------------------------
Jasonhill:
我也經(jīng)常看到要求禁止使用全局變量,在合適的條件下,使用全局變量還是非常有用的。但是程序員還是會(huì)不自覺地傾向于濫用它們,任何變量(全局變量、局部變量、LV2全局變量)在使用時(shí)需要格外小心,“連線”還是最安全的。
我非常討厭上下或者左右堆積大量的控件,在程序框圖中多達(dá)20幾個(gè)層疊順序結(jié)構(gòu)中,到處散布一些全局變量或者局部變量。
至于你提及的生產(chǎn)者消費(fèi)者模式,我還是愿意使用隊(duì)列來完成,使用隊(duì)列可以使我們不需要考慮讀的時(shí)機(jī)問題。
-----------------------------------------------------------------------------------------------------------------------------T
TBOB:
在生產(chǎn)者消費(fèi)者模式中,使用隊(duì)列(我也傾向于使用隊(duì)列,而不是變量)同樣存在問題。消費(fèi)者可能運(yùn)行速度高于消費(fèi)者,此時(shí)可能讀回空數(shù)據(jù),必須在編程中檢查是否是否讀回空數(shù)據(jù)。
----------------------------------------------------------------------------------------------------------------------------
TST:
在生產(chǎn)消費(fèi)者模式使用隊(duì)列時(shí),我愿意使用超時(shí)的默認(rèn)值-1,這意味著消費(fèi)者在沒有數(shù)據(jù)時(shí)不會(huì)執(zhí)行一個(gè)循環(huán),也不需要檢查超時(shí)是否發(fā)生了。
------------------------------------------------------------------------------------------------------------------------------
TITOU:
真是個(gè)好題目!
全局變量是魔鬼嗎?------我愿意這樣回答:不是,只要你遵循了全局變量的工作規(guī)則。
我經(jīng)常建議避免使用全局變量,但是的確在特定的場(chǎng)合,我還是會(huì)使用全局變量,因?yàn)槭褂萌肿兞康拇_非常方便。
使用但不要濫用。
--------------------------------------------------------------------------------------------------------------------------------
ROBERT:
即使在基于文本的編程語言中,采用封裝和抽象本身就傾向于不使用全局變量。理想的結(jié)構(gòu)應(yīng)該是這樣的,如果函數(shù)需要一個(gè)變量,必須從函數(shù)的調(diào)用者哪里接收這個(gè)變量。盡管如此,即使在這樣的編程環(huán)境中,還是需要有限度的和合理的利用全局變量。正如上面的帖子中指出的那樣,一個(gè)寫入者,多個(gè)讀取者。亦或需要在整個(gè)程序應(yīng)用,但是不需要改變的場(chǎng)合。
我經(jīng)常采樣下面的方式。在程序啟動(dòng)時(shí),先運(yùn)行一個(gè)配置函數(shù)或者“參數(shù)設(shè)置”函數(shù),此時(shí)沒有其它的進(jìn)程工作,數(shù)據(jù)采集也尚未進(jìn)行。此時(shí)為程序的其它部分創(chuàng)建全局變量是合理的。
評(píng)論