雖然剛剛翻了翻之前的人寫過的文章,但仍然有些地方不甚了解。首先,class當中,static function和一般的function有什麼不同?什麼情況下需要再class當中宣告 static的function?其次,在讀有關Linux的核心程式碼的時候,看到許多宣告成 static 的函數,為什麼要宣告成 static 的函數呢?這樣的宣告和一般沒有宣告成 static 的函數有什麼不同?最後,就一般而言,inline 函數感覺有點像是把程式碼內嵌,以省略函數呼叫的方式,但我在 linux 的核心程式碼當中,卻看到相當多宣告成 static inline 的函數, static + inline ?這是什麼?有誰能告訴我?
2006-06-03 10:08:37 · 4 個解答 · 發問者 Rody 5 in 電腦與網際網路 ➔ 程式設計
請問大大:
1.『沒有 instance 存在的狀況下』是指在沒有產生實際的class物件的情況下吧?﹙一般物件函數要實際產生物件才能使用,這個就是不用產生物件就能使用的意思吧?﹚
2.『此函數不能夠在runtime 時被作業系統在記憶體中swap out』這句話的意思不太明白,swap out中文的意思應該是交換或置換出去?函數被swap out會怎樣?很糟糕嗎?為什麼核心程式碼不能被swap out?
2006-06-07 06:29:09 · update #1
3.『inline函數只是一個建議,不一定會內嵌』... 嗯... 如果宣告了 inline 卻不內嵌,那代表這個 function 還是會被當成一般函數,進行呼叫跳躍囉?是這個意思嗎?
4.不論如何,非常感謝您的回答~~
2006-06-07 06:29:24 · update #2
感謝giffen大大
根據這樣的說法,我是不是可以說,使用 static 宣告 function 則當進入該函數之後,因為不會被 swap out,所以在這個 function 還沒結束之前,即使 CPU 去處理別的工作,這個 function 使用的記憶體還是會佔用主記憶體,所以當時其他工作的可用記憶體就會因此減少,但是相對當切換回目前的 function 時,則因不需要重新搬動記憶體,所以速度會加快呢?
2006-06-07 17:30:53 · update #3
而按照您這樣的說法,宣告 static inline 如果不被內嵌,CPU 處理到這個 function 時還是必須進行跳躍呼叫,只是即使如此,在這段 function 使用的記憶體都會被保留在主記憶體中,而不會被 Swap out,是這樣的意思嗎?
2006-06-07 17:31:12 · update #4
感謝 giffen, QOO, 及 龍 各位大大的講解
對於 static 對 swap out 的影響,各位大大似乎有不同的見解,我們似乎也很難驗證事實到底如何,但是看起來 static 宣告的函數祇能被同一個檔案的程式呼叫,應該是比較沒有爭議的結論吧?而 inline 宣告的成立與否,看起來是要看 Compiler 或 OS 的心情來決定,而好像只有核心程式碼不會被 swap out,而其他應用程式都有機會?是這樣嗎?我很好奇,怎樣才能寫出不被 swap out 的程式?
2006-06-09 09:22:34 · update #5
感謝 giffen 及 龍 兩位大大的回覆
因為我目前正在研究要使用 RT Linux 每個毫秒呼叫一次的函數 (以此來趨近所謂即時的系統) 因此對時間挺計較的, swap 這個動作也許有機會造成不可預期的時間搶佔, 我擔心會不會有可能把系統給拖垮, 另外, 由於相同的理由, 不知道有沒有可能讓程式在某段時間可以完全使用 CPU 而不會被系統強迫分時呢? (看起來static宣告沒有這個作用)
2006-06-09 18:28:43 · update #6
感謝 giffen 及 龍 兩位大大
其實我的疑慮是來自之前在 Windows - VB 底下, 程式曾經在 RS-232 或 GPIB 的輸出輸入指令上停頓約一秒左右, 而這些指令正常而言都應該是非常快就該執行完畢的, 我無法判斷是什麼原因造成這樣的停頓, 但是如果在每個毫秒發生一次的中斷呼叫當中, 突然來個這種一秒左右的停頓, 我擔心系統會因此垮掉, 而這樣的停頓對我而言完全不可預期 (感覺跟程式無關)
2006-06-10 07:50:21 · update #7
如果不要把這種有機會不預警停頓的程式碼掛在及時中斷呼叫中也許就不用考慮這麼多, 但是偏偏 GPIB 的通訊有時又對回應時間很重視 (30ms之類必須回應), 所以才有這樣的困擾啊... 因此我才想說, 如果執行權不要被奪走, 也許這個問題就不會發生; 提高優先權的方式有系統呼叫可以執行, 但是誠如 龍 所說的, 這並不能保證時間確定不會被搶, 我的中斷呼叫每個ms發生一次, 目前每次執行花費的時間約為 0.0006 ms, 但是如果加上 RS232 及 GPIB 的控制, 正常執行應該也不會出問題, 但如果執行當中停頓了, 那... 後果就很糟了
2006-06-10 07:50:45 · update #8
首先,class當中,static function和一般的function有什麼不同?什麼情況下需要再class當中宣告 static的function?
在class中的static function 不需要instance 即可執行,所以在沒有instance 存在的狀況下要能夠執行class的function 就要宣告成static
其次,在讀有關Linux的核心程式碼的時候,看到許多宣告成 static 的函數,為什麼要宣告成 static 的函數呢?這樣的宣告和一般沒有宣告成 static 的函數有什麼不同?
這個static 的意義是代表此函數不能夠在runtime 時被作業系統在記憶體中swap out,因此核心程式碼大部分都是static
最後,就一般而言,inline 函數感覺有點像是把程式碼內嵌,以省略函數呼叫的方式,但我在 linux 的核心程式碼當中,卻看到相當多宣告成 static inline 的函數, static + inline ?這是什麼?有誰能告訴我?
inline函數只是一個建議,不一定會內嵌.static + inline保證在不內嵌的狀況下此函數也不會被swap out
2006-06-06 21:10:43 · answer #1 · answered by ? 3 · 0⤊ 0⤋
eric對inline見解,我舉雙手同意.
至於eric對static成員函式的講解,我舉雙腳贊成.
不過有關一般的static函式,這我的看法就不一樣了.
static是用來設定一個函式的使用範圍.你如果把一個函式設定為static的話,你只能在那個函式所在的檔案裡呼叫這程式.也就是說在test.cpp這個檔案裡你有一個static函式叫print().你只能在test.cpp裡使用print()這個函式.
你若把static和inline一起用的話,那就表示此函式可能會被C++內崁,其使用範圍只限於在那個函式所在的檔案裡.
2006-06-08 10:48:10 補充:
所以把一個函式設定為static跟此函式在執行時會不會被”swap out”是無關係的.
至於你的問題,以下是我的答案
1. 對.例:
class h
{
public:
static void print() { cout << “hello world” << endl; }
};
要用時:
h::print();
就可以了. P.S. 你如把函式定義寫在class裡的話那其函式是個inline函式
2006-06-08 10:57:33 補充:
2. 所謂”swap out” 的意思是,資料已不在記憶體裡.下次再要用時,VMM會從新從硬碟中讀取. 一個函式的程式碼一開始是存在硬碟裡.你在執行此程式時,VMM會先讀取此函式所有的程式碼.所以在執行時此函式所有的程式碼都在記憶體裡.這樣比較快.但是如果存有此函式的程式碼的記憶體被swap out的話.那下次執行此函式時VMM又會從硬碟裡讀取此函式的程式碼. 也就是說,如無swap out,那每次執行此函式時不需要從硬碟裡讀取.若有swap out的話,那執行此函式時需要先從硬碟裡讀取.若此,當然無swap out的比較快啦.
2006-06-08 10:57:42 補充:
核心程式碼不能被swap out的原因有很多. 一是速度的關係. 二是不可能.拿VMM來說, VMM屬於linux核心程式碼之一.因VMM也是由程式碼寫成.VMM是所謂的虛擬記憶體.絕大多數電腦在執行所需要的資料都是由VMM管理.所以一開始,VMM的程式碼會被存入記憶體以供系統使用.但如果VMM在讀取硬碟裡別的程式碼時若自己的程式碼會被swap out的話那誰來幫VMM讀取其程式碼?
2006-06-08 10:57:56 補充:
3. 如一個inline函式沒被內崁,那就跟一般函式一樣.若被內崁,那此函式就跟巨集(macro)差不多(不完全一樣).
你之後問的那兩個問題,因static並不表示pinned(pinned就是不會被”swap out”).那函式隨時都有可能會被swap out.
懂不懂?不懂請再問
2006-06-09 21:16:00 補充:
giffen,以下乃個人鄙見.若不正確請糾正.若在一般的函式前加static,那並不會改變其執行時程式碼在記憶體裡之住址.更不會影響到這記憶體是否是pinned.在一般的函式前加static只會改變這函式的使用namespace而已.這純粹是由compiler/linker來處理,而跟loader無關.
至於程式速度而言,你說的一點都沒錯.你在程式中並不能控制VMM的page in和page out(除非你用像mlock()的函式).也就是說VMM的page in和page out對任何程式在計算速度時是個公平的變數.
2006-06-09 21:18:56 補充:
rody,在linux裡你可用mlock()來pin記憶體.這樣被pinned的記憶體就不會被swaped out.用完之後可呼叫munlock()來unpin記憶體.
2006-06-10 08:22:01 補充:
hmmm,若每毫秒就呼叫一次.那要看你的母程式(呼叫者)和子程式(被呼叫者)是如何寫啦.有的寫法100分之100會把系統給拖垮.有的寫法卻不會.至於你第二個問題,我是覺得這還是要看你的程式是怎麼寫的.是個應用程式還是個系統程式.是在kernel裡執行還是在user space裡執行.giffen說的沒錯,你可用nice來調整你程式的priority.但那並不會完全保證系統會全天候的執行你的程式.講真的,若不知你那程式是怎麼寫的.我實不知要如何講... :)
2006-06-10 21:02:55 補充:
若此,或許你可在kernel裡interrupt level執行你的程式.因在interrupt level,沒人會跟你搶CPU.不過你若真要在interrupt level裡執行你的程式的話,你要確保你程式所需要的所有資訊都已被pinned.因若在interrupt level裡是不能page out的,若真page out的話系統就會crash.
2006-06-08 06:47:53 · answer #2 · answered by 龍 7 · 0⤊ 0⤋
function static 宣告.
主要的目的. 是要告訴compiler 此function 不要export 給別的檔案參考用.
如檔案a.c 中
寫了static int A();
此A 不能給別的.c 檔用. 也就是說. a.c 中的 A() function 不會被linker 參考到.
2006-06-08 06:39:17 · answer #3 · answered by SiYu 5 · 0⤊ 0⤋
1.的確不用產生物件就可以使用該member funcction,不過還是建議你看一下何謂靜態成員變數?你會對 static function 更瞭解.
2.關於swap你可以參考作業系統相關書籍裡面的虛擬記憶體(Virtual Memory),就是硬碟模擬主記憶體的那個玩意.
3.那要看 Compiler 來決定,
要節省記憶體的情況下會當成一般 function處理.
記憶體充裕而要求速度的時候還是會指令內嵌.
2006-06-08 00:32:19 補充:
static 宣告 function 要分成兩種狀況解釋
opt1:一般的應用程式 Process,仍然會被swap.因為每個Process所用的記憶體(code,data)位置是由OS配置相對位址;萬一發生swap,OS會負責轉成正確位置讓應用程式繼續順利執行.
opt2:Kernel用的function,用絕對位置.發生swap恐怕不只是變慢而已,而是記憶位置錯亂,直接當機.
系統程式與應用程式的考量點是不一樣的.我猜,你是不是把這兩種情況混淆成一樣?
2006-06-09 14:07:58 補充:
我, QOO, 及 龍 對 static 的解釋並沒有衝突之處.
簡單來說 static 是 C/C++ 用來配置記憶體的選項.你別忘了,程式碼(function)和變數一樣需要記憶空間配置,一樣可以用指標來找,一樣有存取權限的問題.
如果你想要的是程式速度,應該把重心放在資料節構和演算法,不是swap這種枝微末節.
swap不是程式語言可以決定的,而是作業系統考量整體效率排程/配置的結果.
如果你這麼不喜歡swap,把config找到,關掉虛擬記憶體不就好了?何必花這麼多力氣研究程式語言?
最後,我還是看不出來我和QOO, 及 龍 的意見有什麼不同的?
2006-06-10 01:53:51 補充:
那麼你用nice,renice指令調高Process的Priority就可以了.(Linux應該有提供API,不過我懶得找.另外,建議別一口氣調太高,可能會造成系統無故停頓,甚至當機.)
一般在DRAM足夠的時候,通常不會做swap.
在OS控制之下的程式,往往是 程式的優先權低->佔用時間少->不常跑->被swap out.
試過times這個function了嗎?
算出來的時間應當可以觀察出,是否符合你的要求?
不過既然要讀到Kernel我猜測應該會修改到Kernel,程式假如黏在Kernel行程管理或Driver的部分,幾乎表示優先權應該是最高的才對.
2006-06-10 01:54:14 補充:
龍,你謙虛了.
我是覺得關鍵上沒錯就好,要清楚完全明確又挑不出毛病的解釋定義.就很累而且很煩了.
2006-06-07 13:54:00 · answer #4 · answered by ? 4 · 0⤊ 0⤋