1. 程式人生 > >C++面試題二---執行緒與程序

C++面試題二---執行緒與程序

經典的執行緒與程序的面試題

1、 執行緒的基本概念、執行緒的基本狀態及狀態之間的關係?
概念:執行緒是程序中執行運算的最小單位,是程序中的一個實體,是被系統獨立排程和分派的基本單位,執行緒自己不擁有系統資源,只擁有一點在執行中必不可少的資源,但它可與同屬一個程序的其它執行緒共享程序所擁有的全部資源。一個執行緒可以建立和撤消另一個執行緒,同一程序中的多個執行緒之間可以併發執行。
狀態:執行、阻塞、掛起阻塞、就緒、掛起就緒
狀態之間的轉換:
準備就緒的程序,被CPU排程執行,變成執行態;
執行中的程序,進行I/O請求或者不能得到所請求的資源,變成阻塞態;
執行中的程序,程序執行完畢(或時間片已到),變成就緒態;
將阻塞態的程序掛起,變成掛起阻塞態,當導致程序阻塞的I/O操作在使用者重啟程序前完成(稱之為喚醒),掛起阻塞態變成掛起就緒態,當用戶在I/O操作結束之前重啟程序,掛起阻塞態變成阻塞態;
將就緒(或執行)中的程序掛起,變成掛起就緒態,當該程序恢復之後,掛起就緒態變成就緒態;

2、 多執行緒的優缺點
優點:
(1)多執行緒技術使程式的響應速度更快 ,因為使用者介面可以在進行其它工作的同時一直處於活動狀態;
(2)佔用大量處理時間的任務使用多執行緒可以提高CPU利用率,即佔用大量處理時間的任務可以定期將處理器時間讓給其它任務;
(3)多執行緒可以分別設定優先順序以優化效能。
缺點:
(1)等候使用共享資源時造成程式的執行速度變慢。這些共享資源主要是獨佔性的資源 ,如印表機等。
(2)對執行緒進行管理要求額外的 CPU開銷,執行緒的使用會給系統帶來上下文切換的額外負擔。
(3)執行緒的死鎖。即對共享資源加鎖實現同步的過程中可能會死鎖。
(4)對公有變數的同時讀或寫,可能對造成髒讀等;
以下是最適合採用多執行緒處理:
(1)耗時或大量佔用處理器的任務阻塞使用者介面操作;
(2)各個任務必須等待外部資源 (如遠端檔案或 Internet連線)。

3、 程序和執行緒的區別
程序和執行緒的關係:
(1)一個執行緒只屬於一個程序,而一個程序可以有多個執行緒,但至少有一個執行緒。
(2)資源分配給程序,同一程序的所有執行緒共享該程序的所有資源
(3)處理機分給執行緒,即真正在處理機上執行的是執行緒
(4)執行緒在執行過程中,需要協作同步。不同程序的執行緒間要利用訊息通訊的方法實現同步。執行緒是程序內的一個執行單元,也是程序內的可排程實體。
程序與執行緒的區別:
(1)排程:執行緒作為排程和分配的基本單位,程序作為擁有資源的基本單位
(2)併發性:不僅程序可以併發執行,同一個程序的多個執行緒之間也可以併發執行
(3)擁有資源:程序是擁有資源的一個獨立單位,執行緒不擁有系統資源,但可以訪問隸屬於程序的資源
(4)系統開銷:在建立或撤銷程序時,由於系統要為之分配和回收資源,導致系統的開銷明顯大於建立或撤銷時程序的開銷

4、 多執行緒同步和互斥有幾種實現方法,都是什麼?
執行緒間的同步方法大體可分為兩類:使用者模式和核心模式。顧名思義,核心模式就是指利用系統核心物件的單一性來進行同步,使用時需要切換核心態與使用者態,而使用者模式就是不需要切換到核心態,只在使用者態完成操作。
使用者模式下的方法有:原子操作(例如一個單一的全域性變數),臨界區。核心模式下的方法有:事件,訊號量,互斥量。

5、 多執行緒同步和互斥有何異同,在什麼情況下分別使用他們?舉例說明。
當有多個執行緒的時候,經常需要去同步這些執行緒以訪問同一個資料或資源。例如,假設有一個程式,其中一個執行緒用於把檔案讀到記憶體,而另一個執行緒用於統計檔案中的字元數。當然,在把整個檔案調入記憶體之前,統計它的計數是沒有意義的。但是,由於每個操作都有自己的執行緒,作業系統會把兩個執行緒當作是互不相干的任務分別執行,這樣就可能在沒有把整個檔案裝入記憶體時統計字數。為解決此問題,你必須使兩個執行緒同步工作。
所謂同步,是指散步在不同程序之間的若干程式片斷,它們的執行必須嚴格按照規定的某種先後次序來執行,這種先後次序依賴於要完成的特定的任務。如果用對資源的訪問來定義的話,同步是指在互斥的基礎上(大多數情況),通過其它機制實現訪問者對資源的有序訪問。在大多數情況下,同步已經實現了互斥,特別是所有寫入資源的情況必定是互斥的。少數情況是指可以允許多個訪問者同時訪問資源。
所謂互斥,是指散佈在不同程序之間的若干程式片斷,當某個程序執行其中一個程式片段時,其它程序就不能執行它們之中的任一程式片段,只能等到該程序執行完這個程式片段後才可以執行。如果用對資源的訪問來定義的話,互斥某一資源同時只允許一個訪問者對其進行訪問,具有唯一性和排它性。但互斥無法限制訪問者對資源的訪問順序,即訪問是無序的。

6、 程序間通訊的方式
(1)管道(pipe)及有名管道(named pipe):管道可用於具有親緣關係的父子程序間的通訊,有名管道除了具有管道所具有的功能外,它還允許無親緣關係程序間的通訊。
(2)訊號(signal):訊號是在軟體層次上對中斷機制的一種模擬,它是比較複雜的通訊方式,用於通知程序有某事件發生,一個程序收到一個訊號與處理器收到一箇中斷請求效果上可以說是一致的。
(3)訊息佇列(message queue):訊息佇列是訊息的連結表,它克服了上兩種通訊方式中訊號量有限的缺點,具有寫許可權得程序可以按照一定得規則向訊息佇列中新增新資訊;對訊息佇列有讀許可權得程序則可以從訊息佇列中讀取資訊。
(4)共享記憶體(shared memory):可以說這是最有用的程序間通訊方式。它使得多個程序可以訪問同一塊記憶體空間,不同程序可以及時看到對方程序中對共享記憶體中資料得更新。這種方式需要依靠某種同步操作,如互斥鎖和訊號量等。
(5)訊號量(semaphore):主要作為程序之間及同一種程序的不同執行緒之間得同步和互斥手段。
(6)套接字(socket):這是一種更為一般得程序間通訊機制,它可用於網路中不同機器之間的程序間通訊,應用非常廣泛

7、 建立執行緒的方式
(1)繼承Thread類
(2)實現Runable介面

8、 C++中多執行緒的實現方式
Windows下通過 api CreateThread(windows.h庫中),Linux下則常用pthread庫(常用的兩個函式是pthread_create和pthread_join),這些都是最底層的實現,最新的C++11標準裡增加了std::thread多執行緒庫,也可以使用第三方庫,比如boost的thread等等。