【面試】線程進程區別

我的理解

面試時候屢次被問到,本身回答感受很通常,回答瞭如下幾點:面試

  • 線程是獨立調度的基本單位,進程是資源分配的基本單位
  • 線程基本不擁有資源,只擁有一點在運行中必不可少的資源,進程擁有 CPU 資源
  • 一個進程能夠包括多個線程,這些線程共享進程資源

資料總結

  1. 擁有資源

進程是資源分配的基本單位,可是線程不擁有資源,線程能夠訪問同一進程的資源算法

  1. 調度

線程是獨立調度的基本單位,同一進程中,線程的切換不會引發進程切換,從一個進程內的線程切換到另外一個進程內的線程會引發進程切換安全

  1. 系統開銷

建立和撤銷進程時,系統都要爲之分配或回收資源,所付出的開銷遠大於建立或撤銷線程時的開銷。一樣的在進程切換時,也會涉及當前執行進程 CPU 環境的保存以及新調度進程 CPU 環境的設置,而線程的切換隻需保存和設置少許寄存器的內容,開銷很小多線程

  1. 通訊方面

進程間通訊須要進程同步和互斥手段的輔助,以保證數據的一致性。而線程間能夠經過直接讀/寫贊成進程中的數據段(如全局變量)來進行通訊。併發

補充

  • 執行過程當中區別,每一個獨立的線程有一個程序運行的入口、順序執行序列和程序的出口,可是線程不能獨立執行,必須依存在應用程序中,由應用程序提供多個線程執行控制
  • 邏輯角度來看,多線程的意義在於在一個應用程序中,有多個執行部分能夠同時執行,可是操做系統沒有將這多個線程看作多個獨立的應用,來實現進程資源的調度和管理以及資源分配
  • 一個線程能夠建立和撤銷另外一個線程,同一個進程中的多個線程之間能夠併發執行

線程好處

  1. 在進程內建立、終止線程要比建立、終止進程快得多
  2. 同一進程內的線程間切換比進程間切換要快,尤爲是用戶級線程間的切換。

後續問題

  1. 線程資源搶佔可能出現什麼問題?

這是面試騰訊的面試題,同一進程中有多個線程共享資源,確定會出現資源的不夠用,簡單來講就是可能出現線程死鎖,這裏我當時有點不願定,覺得只能出現進程死鎖,實際上線程也會出現死鎖,面試官問個人時候我就直接按照進程死鎖的來講了ide

  1. 如何避免這種問題出現?

這個問題就是要考察死鎖發生的條件,如何避免死鎖。我先是簡單介紹了死鎖發生的四個條件,當時也是想既然是死鎖,無論線程仍是進程發生死鎖的條件應該是一致的,就直接說了,後面查資料證實事實就是這樣的,惟一不一樣之處就是死鎖的基本單元不一樣,一個是進程之間,一個是線程之間。測試

死鎖的四個必要條件:spa

  • 互斥條件:一個資源只能被一個進程(線程)使用
  • 請求與保持條件:一個進程(線程)因請求資源而阻塞時,對已得到的資源保持不放
  • 不剝奪條件:進程(線程)已得到的資源,在未完成以前,不能強行剝奪
  • 循環等待條件:若干進程(線程)之間造成一種頭尾相接的循環等待資源關係

死鎖案例:操作系統

package opersystem;

/** * @author YaboSun */
public class DeadLock {
    // 經過一個簡單的例子測試線程死鎖

    public static void main(String[] args) {
        // 線程a
        Thread a = new Thread(new Runnable() {
            @Override
            public void run() {
                DeadLock.method1();
            }
        });

        // 線程b
        Thread b = new Thread(new Runnable() {
            @Override
            public void run() {
                DeadLock.method2();
            }
        });

        a.start();
        b.start();
    }

    private static void method1() {
        synchronized (String.class) {
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("線程 a 嘗試獲取integer.class");
            synchronized (Integer.class){

            }
        }
    }

    private static void method2() {
        synchronized (Integer.class) {
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("線程 b 嘗試獲取 string.class");
            synchronized (String.class){

            }
        }
    }
}

複製代碼

那麼避免死鎖的出現就是破壞其中的必要條件:.net

  • 破壞互斥條件:例如脫機打印機技術容許若干個進程同時輸出,惟一真正請求物理打印機的進程是打印機守護進程
  • 破壞佔有和等待條件:一種實現方式是規定全部進程在開始執行前請求所須要的所有資源
  • 破壞不可搶佔條件
  • 破壞環路等待條件:給資源統一編號,進程只能按編號的順序來請求資源
  1. 銀行家算法

參考: 一句話+一張圖說清楚銀行家算法

當一個進程申請使用資源的時候,銀行家算法經過試探分配給該進程資源,而後經過安全性算法判斷分配後的系統是否處於安全狀態,若不安全則試探分配做廢,讓該進程繼續等待

如何判斷系統處於安全狀態?

若是沒有死鎖發生, 而且即便全部進程忽然請求對資源的最大需求,也仍然存在某種調度次序可以使得每個進程運行完畢,則稱該狀態是安全的。

相關文章
相關標籤/搜索