天天看點

個人不熟悉的面試題目(作業系統)

運作->退出:導緻程序終止的原因有:正常完成、超過時限、系統無法滿足程序需要的記憶體空間、程序試圖通路不允許通路的記憶體單元(越界)、算術錯誤(如除以0或存儲大于硬體可以接納的數字)、父程序終止(作業系統可能會自動終止該程序所有的後代程序)、父程序請求終止後代程序等。

1.     程序與線程的差別。

在多線程環境中,一個程序被定義成資源配置設定的機關和一個被保護的機關,與程序相關聯的有:

(1)存放程序映像(程式、資料、棧和程序控制塊中定義的屬性的集合)的虛拟位址空間

(2)受保護的對處理器、其他程序(用于程序間通信)、檔案和IO資源(裝置和通道)的通路

在一個程序中,可能有一個或多個線程,每個線程有:

線程執行狀态(運作、就緒等)

² 在未運作時儲存的線程上下文

² 一個執行棧

² 用于每個線程局部變量的靜态存儲空間

² 與程序内的其他線程共享的對程序的記憶體和資源的通路

在多線程程序中,每個線程都有一個獨立的棧,還有獨立的線程控制塊用于包含寄存器值、優先級和其他與線程相關的狀态資訊。

在大多數作業系統中,獨立程序間的通信需要核心的介入,以提供保護和通信所需要的機制。但是,由于在同一個程序中的線程共享記憶體和檔案,他們無需調用核心就可以互相通信。

2.    程序通信的幾種方式。

程序間通信主要包括管道, 系統IPC(包括消息隊列,信号量,共享存儲), SOCKET。

  管道包括三種:1)普通管道PIPE, 通常有種限制,一是半雙工,隻能單向傳輸;二是隻能在父子程序間使用. 2)流管道s_pipe: 去除了第一種限制,可以雙向傳輸. 3)命名管道:name_pipe,去除了第二種限制,可以在許多并不相關的程序之間進行通訊.

系統IPC的三種方式類同,都是使用了核心裡的辨別符來識别.

# 管道( pipe ):管道是一種半雙工的通信方式,資料隻能單向流動,而且隻能在具有親緣關系的程序間使用。程序的親緣關系通常是指父子程序關系。

# 有名管道 (namedpipe) : 有名管道也是半雙工的通信方式,但是它允許無親緣關系程序間的通信。

# 信号量( semophore) : 信号量是一個計數器,可以用來控制多個程序對共享資源的通路。它常作為一種鎖機制,防止某程序正在通路共享資源時,其他程序也通路該資源。是以,主要作為程序間以及同一程序内不同線程之間的同步手段。

# 消息隊列( messagequeue ) : 消息隊列是由消息的連結清單,存放在核心中并由消息隊列辨別符辨別。消息隊列克服了信号傳遞資訊少、管道隻能承載無格式位元組流以及緩沖區大小受限等缺點。

信号(signal) 機制和Linux信号量(semaphore)機制的差別  http://blog.csdn.net/langjian2012/article/details/39717903

# 信号 ( sinal ) : 信号是一種比較複雜的通信方式,用于通知接收程序某個事件已經發生。

# 共享記憶體( sharedmemory ) :共享記憶體就是映射一段能被其他程序所通路的記憶體,這段共享記憶體由一個程序建立,但多個程序都可以通路。共享記憶體是最快的 IPC 方式,它是針對其他程序間通信方式運作效率低而專門設計的。它往往與其他通信機制,如信号量,配合使用,來實作程序間的同步和通信。

# 套接字( socket ) : 套解口也是一種程序間通信機制,與其他通信機制不同的是,它可用于不同機器間的程序通信。

3.線程同步幾種方式。(一定要會寫生産者、消費者問題,完全消化了解)

程序中線程同步的四種常用方式:

(1)臨界區(CriticalSection)

當多個線程通路一個獨占性共享資源時,可以使用臨界區對象。擁有臨界區的線程可以通路被保護起來的資源或代碼段,其他線程若想通路,則被挂起,直到擁有臨界區的線程放棄臨界區為止。具體應用方式:

(1、 定義臨界區對象

(2、 在通路共享資源(代碼或變量)之前,先獲得臨界區對象

(3、 通路共享資源後,則放棄臨界區對象

(2)事件(Event)

事件機制,則允許一個線程在處理完一個任務後,主動喚醒另外一個線程執行任務。比如在某些網絡應用程式中,一個線程如A負責偵聽通信端口,另外一個線程B負責更新使用者資料,利用事件機制,則線程A可以通知線程B何時更新使用者資料。

(3)互斥量(Mutex)

互斥對象和臨界區對象非常相似,隻是其允許在程序間使用,而臨界區隻限制與同一程序的各個線程之間使用,但是更節省資源,更有效率。

(4)信号量(Semphore)

 當需要一個計數器來限制可以使用某共享資源的線程數目時,可以使用“信号量”對象。Semaphore類對象儲存了對目前通路某一個指定資源的線程的計數值,該計數值是目前還可以使用該資源的線程數目。如果這個計數達到了零,則所有對這個Semaphore類對象所控制的資源的通路嘗試都被放入到一個隊列中等待,直到逾時或計數值不為零為止。

4.線程的實作方式. (也就是使用者線程與核心線程的差別)

線程的實作可分為兩大類,使用者級線程(user-levelthread,ULT)和核心級線程(kernel-levelthread,KLT)。後者又稱為核心支援的線程或輕量級程序。

(1)使用者級線程

在一個純粹的使用者級線程軟體中,有關線程管理的所有工作都由應用程式完成,核心意識不到線程的存在。

使用使用者級線程而不是核心級線程的優點有:

  • 線程切換不需要核心态特權,程序并不需要為了線程管理而切換到核心态
  • 可以為應用程式量身定做排程算法而不擾亂底層的作業系統排程程式
  • 使用者級線程可以在任何作業系統中運作,不需要對底層核心進行修改以支援使用者級線程

相比核心級線程,使用者級線程有兩個明顯的缺點:

  • 許多系統調用都會引起阻塞,當使用者級線程執行一個系統調用時,不僅這個線程會被阻塞,程序中的所有線程都會被阻塞
  • 在純粹的使用者級線程政策中,一個多線程應用程式不能利用多處理技術

(2)核心級線程

在一個純粹的核心級線程軟體中,有關線程管理的所有工作都是由核心完成的,應用程式部分沒有進行線程管理的代碼,隻有一個到核心線程設施的應用程式程式設計接口(API)。

該方法克服了使用者級線程方法的兩個基本缺陷:核心可以同時把同一個程序的多個線程排程到多個處理器中;如果程序中的一個線程被阻塞,核心可以排程同一個程序中的另一個線程。相比使用者級線程它的主要缺點是:把控制從一個線程傳送到程序中的另一個線程時,需要到核心的狀态切換。

某些作業系統采用組合使用者級線程和核心級線程的方法,同一個應用程式中的多個線程可以在多個處理器上并行的運作,某個會引起阻塞的系統調用不會阻塞整個程序。如果設計正确,該方法會結合兩種線程的優點,同時減少他們的缺點。

5.使用者态和核心态的差別。

當一個任務(程序)執行系統調用而陷入核心代碼中執行時,我們就稱程序處于核心運作态(或簡稱為核心态)。此時處理器處于特權級最高的(0級)核心代碼中執行。當程序處于核心态時,執行的核心代碼會使用目前程序的核心棧。每個程序都有自己的核心棧。當程序在執行使用者自己的代碼時,則稱其處于使用者運作态(使用者态)。即此時處理器在特權級最低的(3級)使用者代碼中運作。

特權級顯然是非常有效的管理和控制程式執行的手段,是以在硬體上對特權級做了很多支援,就Intel x86架構的CPU來說一共有0~3四個特權級,0級最高,3級最低,硬體上在執行每條指令時都會對指令所具有的特權級做相應的檢查。雖然使用者态下和核心态下工作的程式有很多差别,但最重要的差别就在于特權級的不同,即權力的不同。運作在使用者态下的程式不能直接通路作業系統核心資料結構和程式。

當我們在系統中執行一個程式時,大部分時間是運作在使用者态下的,在其需要作業系統幫助完成某些它沒有權力和能力完成的工作時就會切換到核心态。

 使用者态和核心态的轉換

1)使用者态切換到核心态的3種方式

a. 系統調用

這是使用者态程序主動要求切換到核心态的一種方式,使用者态程序通過系統調用申請使用作業系統提供的服務程式完成工作,而系統調用的機制其核心還是使用了作業系統為使用者特别開放的一個中斷來實作,例如Linux的int 80h中斷。

b. 異常

當CPU在執行運作在使用者态下的程式時,發生了某些事先不可知的異常,這時會觸發由目前運作程序切換到處理此異常的核心相關程式中,也就轉到了核心态,比如缺頁異常。

c. 外圍裝置的中斷

當外圍裝置完成使用者請求的操作後,會向CPU發出相應的中斷信号,這時CPU會暫停執行下一條即将要執行的指令轉而去執行與中斷信号對應的處理程式,如果先前執行的指令是使用者态下的程式,那麼這個轉換的過程自然也就發生了由使用者态到核心态的切換。比如硬碟讀寫操作完成,系統會切換到硬碟讀寫的中斷處理程式中執行後續操作等。

這3種方式是系統在運作時由使用者态轉到核心态的最主要方式,其中系統調用可以認為是使用者程序主動發起的,異常和外圍裝置中斷則是被動的。

2)具體的切換操作

從觸發方式上看,可以認為存在前述3種不同的類型,但是從最終實際完成由使用者态到核心态的切換操作上來說,涉及的關鍵步驟是完全一緻的,沒有任何差別,都相當于執行了一個中斷響應的過程,因為系統調用實際上最終是中斷機制實作的,而異常和中斷的處理機制基本上也是一緻的,涉及到由使用者态切換到核心态的步驟主要包括:

[1] 從目前程序的描述符中提取其核心棧的ss0及esp0資訊。

[2] 使用ss0和esp0指向的核心棧将目前程序的cs,eip,eflags,ss,esp資訊儲存起來,這個過程也完成了由使用者棧到核心棧的切換過程,同時儲存了被暫停執行的程式的下一條指令。

[3] 将先前由中斷向量檢索得到的中斷處理程式的cs,eip資訊裝入相應的寄存器,開始執行中斷處理程式,這時就轉到了核心态的程式執行了。