進程與線程
概念:
進程:進程是處於執行期的程序,通常還包含其他資源,如:打開的文件,掛起的信號,內核內部數據,處理器狀態,一個或多個具有內存映射的內存地址空間及一個或多個執行線程,數據段等。它是資源分配的基本單位。
線程:線程是進程中的活動對象,每個線程都擁有一個獨立的程序計數器、進程棧和一組進程寄存器。它是調度的基本單位,在Linux中線程也是一個輕量級的進程。
參考理解:http://www.ruanyifeng.com/blog/2013/04/processes_and_threads.html
區別:
- 資源分配:進程是資源分配的基本單位,線程是調度的基本單位。
- 進程與進程之間是獨立的,一個進程異常終止不會影響其他進程;線程之間大部分資源是共享的,一個線程異常終止會影響其他線程並使其終止。
- 線程的上下文切換比進程上下文切換快
- 線程佔用資源比進程小
- 線程大部分資源共享,但是也有自己的私有數據,如棧空間,錯誤碼,上下文,線程ID等。
- 進程與進程之間是獨立的,在併發過程中,用同步互斥少,相對安全,代碼編寫容易;線程之間大部分資源共享,所有需要加上同步互斥鎖。
- 線程創建出來的線程是平等的,進程創建出來的進程就是該進程的子進程。
聯繫:
- 線程是活動在進程內部,一個進程可以有一個或多個線程。
- 一個線程結束,進程不一定會退出,而一個進程退出,線程也會退出。
- 進程中的資源給多個線程共享,包括虛擬內存和全局變量等。
- 當進程只有一個線程時,可以認爲進程就是線程。
進程描述符:
一個進程中有三大塊:進程控制塊(PCB)、數據段、代碼段。
當一個程序被加載到內存之後,內核會爲他分配一個PCB,這裏PCB就是task_struct結構,稱之爲“進程描述符”。
task_struct主要信息:
- 標識符:用來描述本進程的唯一標識符,區別其他進程。
- 狀態:用來表示當前進程的狀態,退出碼,退出信號。
- 優先級:相對於其他進程之間的優先級。
- 程序計數器:用於記錄程序的下一條指令的地址。
- 內存指針:其中有代碼和數據相關的指針,還有共享內存塊指針。
- 上下文:進程執行時寄存器中的數據。
- I/O狀態:包括顯示I/O請求,分配I/O設備和被進程使用的文件列表。
- 記賬信息:其中包含各種時間。
- 其他
進程五種運行狀態:
運行狀態(TASK_RUNNING):是指正在使用CPU或者正在等待CPU的進程,就是常用top命令看到的,處於R狀態(Runing或Runable)的進程。
可中斷狀態(TASK_INTERRUPTIBLE):進程正處於可中斷等待狀態(被阻塞),系統不會調度該進程進行執行。當系統產生一箇中斷或者釋放了進程正在等待的資源,或者進程收到一個信號,都可以喚醒進程轉換到運行狀態。
不可中斷狀態(TASK_UNINTERRUPTIBLE):除了就算是接收到信號也不會被喚醒或準備投入運行外,這個狀態與可打斷狀態相同。這個狀態通常在進程必須在等待時不受干擾或事件很快就會發生時出現。就是常用top命令看到,處於D狀態(Disk Sleep)的進程,不可中斷狀態實際上是系統對進程和硬件設備的一種保護機制,比如說當一個進程向磁盤讀寫數據時,爲了保證數據的一致性,在得到磁盤迴復前,它是不能被其他進程或者中斷所打斷的。
暫停狀態(TASK_STOPPED):進程停止執行;進程沒有投入運行也不能投入運行。通常這種狀態發生在接收SIGSTOP、SIGTSTP、SIGTTIN、SIGTTOU等信號的時候。
僵死狀態(TASK_ZOMBIE):當進程已停止運行,但其父進程還沒有詢問其狀態時,則稱該進程處於僵死狀態。
進程上下文:
Linux按照特權等級,把進程的運行空間分爲內核空間和用戶空間,對應下圖中,CPU特權等級的Ring0和Ring3.
內核空間(Ring0)具有最高特權,可以直接訪問所有資源;
用戶空間(Ring3)只能訪問受限資源,不能直接訪問內存等硬件設備,必須通過系統調用陷入到內核中,才能訪問這些特權資源。
那麼,進程既可以在用戶空間運行,又可以在內核空間運行。
進程在用戶空間運行時,稱爲進程的用戶態。
當進程陷入內核空間的生活,稱爲進程的內核態。
當用戶態的進程執行了一個系統調用或觸發了某個異常,它就會陷入內核空間,此時,就是處於進程上下文中。