並發程序是指可以被同時發起執行的程序
並行程序被設計成可以在並行的硬件上執行的並發程序。
並發程序代表了所有可以實現並發行為的程序,它是一個寬泛的概念,其中包含了並行程序。
inter-process communication(進程間通信)
- 基於通信的IPC方法:又分為以數據傳送為手段的IPC方法(傳送字節流的管道pipe和傳送結構化的消息對象的消息隊列message queue)和以共享內存(shared memory)為手段的最快的一種IPC方法
- 基於信號的IPC方法:即我們常說的操作系統的信號(signal)機制,它是唯一的一種異步IPC方法。
- 基於同步的IPC方法:最重要的就是信號量(semaphore)
go支持的IPC方法有管道、信號和socket.
進程:我們把一個程序的執行稱為一個進程。(進程用於描述程序的執行過程)
進程是操作系統進行資源分配的一個基本單位。
進程使用fork(一個系統調用函數)可以創建若干個新的進程,前者稱為后者的父進程,后者稱為前者的子進程。每個子進程都是源自它的父進程的一個副本,它會獲得父進程的數據段、堆和棧的副本,並與父進程共享代碼段。
每一個副本都是獨立的,子進程對屬於它的副本的修改對其父進程和兄弟進程(同父進程)都是不可見的,反之亦然。全盤復制父進程的數據是一種相當低效的做法。linux系統內核使用寫時復制(copy on write 簡稱COW)等技術來提高進程創建的效率。
通過go 標准庫os可以查看當前進程的PID和PPID
pid := os.Getpid()
ppid := os.Getppid()
注:PID並不傳達與進程有關的任何信息。它只是一個用了唯一標識進程的數字而已。
進程的屬性信息只包含在內核中與PID對應的進程描述符里。
PPID體現了兩個進程之間的親緣關系。
進程的狀態:
- 可運行狀態(TASK_RUNNING,簡稱R)
- 可中斷的睡眠狀態(TASK_INTERRUPTIBLE,簡稱為S),當進程正在等待某個事件(如網絡連接或者信號量)到來是,會進入此狀態。
- 不可中斷的睡眠狀態(TASK_UNINTERRUPTIBLE,簡稱為D),此狀態與可中斷的睡眠狀態唯一的區別就是它不可被打斷。這意味着處於此中狀態的進程不會對任何信號做出響應。發給此狀態的進程的信號直到它從該狀態轉出才會被傳遞過去。處於此狀態的進程通常是在等待一個特殊的事件,如等待同步的I/O操作完成。
- 暫停狀態或者跟蹤狀態(TASK-STOPPED或者TASK_TRACED,簡稱為T),向進程發送SIGSTOP信號,就會使該進程轉入暫停狀態,除非該進程正處於不可中斷的睡眠狀態。向正處於暫停狀態的進程發送SIGCONT信號,會使該進程轉向可運行狀態。
- 僵屍狀態(TASK_DEAD-EXIT_ZOMBIE,簡稱為Z),處於此狀態的進程即將結束運行,該進程占用的絕大多數資源也都已經被回收,不過還有一些信息未刪除。如退出碼以及一些系統信息。之所以保留這些信息,是考慮到該進程的父進程可能需要他們。由於此時的進程主體已經被刪除而只剩下一個空殼,故此狀態才稱為僵屍狀態。
- 退出狀態(TASK_DEAD-EXIT_DEAD,簡稱為X)。在進程退出的過程中,有可能連退出碼和統計信息都不需要保留。當一個進程消亡的時候,內核會給其父進程發送SIGCHLD信號以告知情況)。
內存區域:操作系統在內存上划分一個范圍,如下
32位計算機中可有效標識2^32個內存單元
64位計算機中可有效標識2^64個內存單元
TASK_SIZE是兩個空間的分界線,其值由所在計算機的體系結構決定,虛擬內存的最大容量與實際的物理內存大小無關,內核和CPU會負責維護虛擬內存與物理內存之間的映射關系。
內核會為每個用戶進程分配的是虛擬內存而不是物理內存。每個用戶進程的虛擬內存互不可見。
內核把進程的虛擬內存划分為若干頁page, 而物理內存單元的划分由CPU負責,一個物理內存單元稱為一個頁框 page frame.