在Linux系统下实现进程,Linux进程学习(一)之Linux进程的基本知识和实现
最近一周學習了Linux?進程編程的知識,現對其總結如下。
在第一部分中我們先對進程的基本概念以及在Linux 中是如何來現實進程的進行介紹
Tiger-John說明?:
許多人在學習中只注重如何編程,卻忘了注重原理,不去深究其基本原理。其實操作系統的原理就好比金庸武俠小說的內功一樣,而所有的具體實現如:Linux操作系統,uc/os操作系統都只是武功招式而已。如果我們內功學的很好的話,再來學習具體的實現過程是很快的。而且也會對其知識有更加本質的了解。
一.進程的基本概念:?1.為什么計算機操作系統要引進進程:?在操作系統中引入進程的目的是為了使多個程序并發執行?,以改善資源利用率及提高系統吞吐量。?2.進程的概念:?進程是程序的一次執行,進程是擁有資源的最小單位和調度單位(在引入線程的操作系統中,線程是最小的調度單位)?3.進程由什么組成?進程由進程控制塊(PCB),數據,程序3部分組成。其中PCB是進程的靈魂。?4.進程的狀態:?進程的三種最基本的狀態是:運行態(running),就緒態(readying),阻塞態(block)?5.進程和程序的區別:?進程和程序的主要區別是進程是動態的,程序是靜態的。進程時運行中的程序,程序是一些保存在硬盤上的可執行的代碼。?6.進程的優點和缺點
(任何事物都是有其兩面性。我們在學習的時候要注意其優點和缺點。人們也就再發現事物缺點的過程中,不斷的去改善它,從而引入了新的事物。在操作系統的學習過程中,我們會發現很多這樣的例子。人們在不斷追求完美的過程中,不斷的引入新的知識點--進程和線程的出現就足可以說明這一切)
優點:使多個程序并發執行?缺點:程序并發執行時付出了巨大的時空開銷,每個進程在進行切換時身上帶了過多的“累贅”導致系統效率降低。?于是人們為了解決這個缺點想到讓進程在并行時不擁有資源---從而引入了線程的概念:即線程本身不擁有資源或者是很少的資源,進程只是擁有資源的基本單位,線程是調度的基本單位?7.線程的引入:?在操作系統中引入線程則是為了減少程序并發執行時所付出的時空開銷,使操作系統具有更好的并發性。?二.Linux中是如何具體實現進程和線程?1.在linux中通過task_struct結構體來描述進程的PCB,我們可以在include/linux/sched.h中看到對進程task_struct的定義和進程狀態的描述。?1>linux中的進程狀態?a.運行狀態:進程正在運行或在運行隊列中等待運行 。
b.可中斷等待狀態:進程正在等待某個事件完成(如等待數據到達)。等待過程中可以被信號或定時器喚醒。?c.不可中斷等待狀態:進程正在等待某個事件完成并且等待中不可以被信號或定時器喚醒,必須一直等待到事件發生。
d.僵死狀態:進程已終止,但進程描述符依然存在,直到父進程調用wait()函數后釋放。?e.停止狀態:進程因為收到SINSTOP,SIGSTP,SIGTIN,SGIOU信號后停止運行或者該進程正在被跟蹤。
Tiger-john說明:
1在include/linux/sched.h?中我們可以看到Linxu中進程狀態的具體實現:?#defineTASK_RUNNING?0
#defineTASK_INTERRUPTIBLE?1
#defineTASK_UNINTERRUPTIBLE?2
#defineTASK_ZOMBIE?4
#defineTASK_STOPPED?8
其中:
TASK_RUNNING是就緒態,進程當前只等待CPU資源。
TASK_INTERRUPTIBLE和TASK_UNINTERRUPTIBLE都是阻塞態,進程當前正在等待除CPU外的其他系統資源;前者可以被信號喚醒,后者不可以。
TASK_ZOMBIE是僵尸態,進程已經結束運行,但是進程控制塊尚未注銷。
TASK_STOPPED是掛起狀態,主要用于調試目的。進程接收到SIGSTOP信號后會進入該狀態,在接收到SIGCONT后又會恢復運行。
2.我們可以在終端中通過命令ps或pstree查看當前系統中的進程?用ps命令可以查看進程的當前狀態。運行狀態為R,可中斷等待狀態為S,不可中斷等待狀態為D,僵死狀態為Z,停止狀態為T。
實例:
think@ubuntu:~$ ps -eo pid,stat?PID?STAT?1?Ss?2?S?3?S?37?SN?364?Ss?371?S<
442?S
1081?Ssl?1085?Ssl?1203?Ss+
3782?Ss
3803?R+
Tiger-John說明:
在運行結果中有一些后綴字符,其意義分別為
例如:Ssl說明該進程處于可中斷等待狀態,且該進程為會話首進程,而且是一個多線程的進程。
2.linux系統的進程間通信有哪幾種方式?1>管道( pipe ):管道是一種半雙工的通信方式,數據只能單向流動,而且只能在具有親緣關系的進程間使用?。進程的親緣關系通常是指父子進程關系。
2>有名管道 (named pipe) : 有名管道也是半雙工的通信方式,但是它允許無親緣關系進程間的通信?。
3>信號量( semophore ) :信號量是一個計數器,可以用來控制多個進程對共享資源的訪問。它常作為一種鎖機制,防止某進程正在訪問共享資源時,其他進程也訪問該資源。因此,主要作為進程間以及同一進程內不同線程之間的同步手段。?4>消息隊列( message queue ) :消息隊列是消息的鏈表,存放在內核中并由消息隊列標識符標識。消息隊列克服了信號傳遞信息少、管道只能承載無格式字節流以及緩沖區大小受限等缺點。
5> 信號 ( sinal ) :信號是一種比較復雜的通信方式,用于通知接收進程某個事件已經發生。
6> 共享內存( shared memory ):共享內存就是映射一段能被其他進程所訪問的內存,這段共享內存由一個進程創建,但多個進程都可以訪問。共享內存是最快的 IPC方式,它是針對其他進程間通信方式運行效率低而專門設計的。它往往與其他通信機制,如信號兩,配合使用,來實現進程間的同步和通信。
7>套接字( socket ) :套解口也是一種進程間通信機制,與其他通信機制不同的是,它可用于不同及其間的進程通信。?3.進程控制?1>linux進程控制包括創建進程,執行進程,退出進程以及改變進程優先級等。?在linux系統中,用于對進程進行控制的系統調用有:?a.fork:用于創建一個新進程。?b.exit :用于終止進程?c.exec :用于執行一個應用程序?d.wait :將父進程掛起,等待子進程終止?e.getpid :獲取當前進程的進程ID?f.nice?: 該變進程的優先級?4.進程標識?1>Linux操作系統中,每個進程都是通過唯一的進程ID標識的。進程ID是一個非負數。每個進程除了進程ID外還有一些其它信息,都可以通過相應的函數獲得。
2>主要的函數有:
pid_tgetpid(void) :獲得進程ID
pid_t getppid(void):獲得進程父進程的ID
pid_tgetuid(void)?:獲得進程的實際用戶ID
pid_t geteuid(void) :獲得進程的有效用戶ID
pid_t getgid(void) : 獲得進程的實際組ID
pid_t getegid(void) 獲得進程的有效組ID
Tiger-Johen說明:?這些函數的聲明在sys/types.h和unistd.h 頭文件中。?2>用戶ID和組ID的相關概念?a.實際用戶ID(uid) :標識運行該進程的用戶
b.有效用戶ID( euid): 標識以什么用戶身份來運行進程。
例如:一個普通用戶A,運行了一個程序,而這個程序是以root 身份來運行的,著程序運行時就具有root權限。此時,實際用戶ID時A用戶的ID,而有效用戶ID是root用戶ID
3>函數實例:?表頭文件:#include
#include
函數定義:pid_t getpid(void)
函數說明:getpid()用來取得目前進程的進程識別碼,許多程序利用取到的此值來建立臨時文件,以避免臨時文件相同帶來的問題
返回值:目前進程的進程識別碼
函數實例:
#include
#include?#include
main()
{
printf("pid = %d/n", getpid());
}
三.進程的內存映像?1.Linux下程序轉化成進程?a.Linux下C程序的生成分為4個階段:
預編譯
編譯
匯編
鏈接
Tiger-Johen說明:
編譯器gcc進過預編譯,編譯,匯編3個步驟將源程序文件轉換為目標文件。
b.當程序執行時,操作系統將可執行程序復制到內存中。程序轉化為進程通常需要經過以下步驟:
內核將程序讀入內存,為程序分配內存空間
內核為該進程分配進程標識符(PID)和其他資源
內核為該進程保存PID及相應的狀態信息,把進程放到運行隊列中等待執行。程序轉化為進程后就可以被操作系統的調度程序執行了。
2.進程的內存映像?a.進程的內存映像是指內核在內存中如何存放可執行程序文件?。在將程序轉化為進程的過程中,操作系統將可執行程序由硬盤復制到內存中。
b.linux下程序映像的一般布局如下:(從低地址到高地址)
1>代碼段:代碼段是只讀的,可被多個進程共享。
2>數據段: 存儲已被初始化的變量,包括全局變量和已被初始化的靜態變量。
3>未初始化數據段:存儲未被初始化的靜態變量,它也被稱為bss段
4>堆:用于存放程序運行中動態分配的變量
5>棧:用戶函數調用,保存函數的返回地址,函數的參數,函數內部定義的局部變量。
Tiger-Johen說明:
可執行程序和內存映像的區別?:
a.可執行程序位于磁盤中而內存映像位于內存中;
b.可執行程序沒有堆棧,因為程序 被加載到內存中才會分配堆棧;
c.可執行程序雖然也有未初始化數據段但它并不被儲存在位于硬盤中的可執行文件中;
d.可執行程序時靜態的,不變的,而內存映像隨著程序的執行時在動態變化的
總結
以上是生活随笔為你收集整理的在Linux系统下实现进程,Linux进程学习(一)之Linux进程的基本知识和实现的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: android微信支付坑,微信支付踏坑之
- 下一篇: python3.8.2中文手册chm_3
