驅動軟件工程師筆試題

1、寫一段 C 代碼讓程序跳轉到地址是 0x8000 0000 的位置執行

答:(*(void(*)(void))0x100000)();或者((void(*)(void))0x100000)();


2、簡述static 關鍵字的作用。

答:1)在函數體內,static 變量的作用範圍爲該函數體,不同於auto 變量,該變量的內存只被分配一次,因此其值在下次調用時仍維持上次的值。

2)在模塊內的static 全部變量可以被模塊內所有函數訪問,但不能被模塊外其他函數訪問。

3)在模塊內的static 函數只可被這一模塊內的其他函數調用,這個函數的使用範圍被限制在聲明它的模塊內。


3、簡要敘述進程和線程這兩個概念。

答:進程是指一個程序在一個數據集合上的一次運行過程。

線程是進程中的一個實體,是被系統獨立調度和執行的基本單位。

進程是程序的一次執行。線程可以理解爲進程中執行的一段程序片段。


4、請簡述自旋鎖和信號量兩個概念並對他們作出比較。

答:1)自旋鎖
自旋鎖是專爲防止多處理器併發而引入的一種鎖,它在內核中大量應用於中斷處理等部分(對於單處理器來說,防止中斷處理中的併發可簡單採用關閉中斷的方式,不需要自旋鎖)。
自旋鎖最多隻能被一個內核任務持有,如果一個內核任務試圖請求一個已被爭用(已經被持有)的自旋鎖,那麼這個任務就會一直進行忙循環——旋轉——等待鎖重新可用。要是鎖未被爭用,請求它的內核任務便能立刻得到它並且繼續進行。自旋鎖可以在任何時刻防止多於一個的內核任務同時進入臨界區,因此這種鎖可有效地避免多處理器上併發運行的內核任務競爭共享資源。
事實上,自旋鎖的初衷就是:在短期間內進行輕量級的鎖定。一個被爭用的自旋鎖使得請求它的線程在等待鎖重新可用的期間進行自旋(特別浪費處理器時間),所以自旋鎖不應該被持有時間過長。如果需要長時間鎖定的話, 最好使用信號量。
自旋鎖的基本形式如下:
spin_lock(&mr_lock);
//臨界區
spin_unlock(&mr_lock);
因爲自旋鎖在同一時刻只能被最多一個內核任務持有,所以一個時刻只有一個線程允許存在於臨界區中。這點很好地滿足了對稱多處理機器需要的鎖定服務。在單處理器上,自旋鎖僅僅當作一個設置內核搶佔的開關。如果內核搶佔也不存在,那麼自旋鎖會在編譯時被完全剔除出內核。
簡單的說,自旋鎖在內核中主要用來防止多處理器中併發訪問臨界區,防止內核搶佔造成的競爭。另外自旋鎖不允許任務睡眠(持有自旋鎖的任務睡眠會造成自死鎖——因爲睡眠有可能造成持有鎖的內核任務被重新調度,而再次申請自己已持有的鎖),它能夠在中斷上下文中使用。
死鎖:假設有一個或多個內核任務和一個或多個資源,每個內核都在等待其中的一個資源,但所有的資源都已經被佔用了。這便會發生所有內核任務都在相互等待,但它們永遠不會釋放已經佔有的資源,於是任何內核任務都無法獲得所需要的資源,無法繼續運行,這便意味着死鎖發生了。自死瑣是說自己佔有了某個資源,然後自己又申請自己已佔有的資源,顯然不可能再獲得該資源,因此就自縛手腳了。

2)信號量
Linux中的信號量是一種睡眠鎖。如果有一個任務試圖獲得一個已被持有的信號量時,信號量會將其推入等待隊列,然後讓其睡眠。這時處理器獲得自由去執行其它代碼。當持有信號量的進程將信號量釋放後,在等待隊列中的一個任務將被喚醒,從而便可以獲得這個信號量。
信號量的睡眠特性,使得信號量適用於鎖會被長時間持有的情況;只能在進程上下文中使用,因爲中斷上下文中是不能被調度的;另外當代碼持有信號量時,不可以再持有自旋鎖。
信號量基本使用形式爲:
static DECLARE_MUTEX(mr_sem);//聲明互斥信號量
if(down_interruptible(&mr_sem))
//可被中斷的睡眠,當信號來到,睡眠的任務被喚醒
//臨界區
up(&mr_sem);

3)信號量和自旋鎖區別
雖然聽起來兩者之間的使用條件複雜,其實在實際使用中信號量和自旋鎖並不易混淆。注意以下原則:
如果代碼需要睡眠——這往往是發生在和用戶空間同步時——使用信號量是唯一的選擇。由於不受睡眠的限制,使用信號量通常來說更加簡單一些。如果需要在自旋鎖和信號量中作選擇,應該取決於鎖被持有的時間長短。理想情況是所有的鎖都應該儘可能短的被持有,但是如果鎖的持有時間較長的話,使用信號量是更好的選擇。另外,信號量不同於自旋鎖,它不會關閉內核搶佔,所以持有信號量的代碼可以被搶佔。這意味者信號量不會對影響調度反應時間帶來負面影響。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章