Linux 程式管理

背對背依靠發表於2022-07-15

基礎知識

程式

核心的功能和作用:檔案系統管理、網路管理、程式管理、記憶體管理等,屬於linux最基礎的功能

程式:process,正在執行中的程式的一個副本。允許有多個程式同時執行。

#作業系統負責分配cpu執行程式的順序和時間

#副本:把磁碟上的指定檔案載入到記憶體進行執行  執行多次就會有多個副本

#多例項:一個程式生成多個副本,每個副本在記憶體中獨立執行

#程式是資源使用的分配單位,程式存在宣告週期

#PID:程式的唯一標號

程式建立過程: #程式的父子關係:寫實複製
1. 作業系統啟動的時候有個總程式(系統的第一個程式):centos6--init  centos7及以上--systemd

2. 後續的所有程式都是總程式生成的,一次推類,構成一個樹狀結構,c語言使用fork()函式建立子程式

#父程式建立子程式的過程:
父程式在記憶體中佔有一片空間,建立子程式的時候,此時子程式用的記憶體空間是父程式那一塊空間。當子程式產生資料更新以後,就會複製父程式的空間來作為自己獨立的空間。

執行緒

執行緒:程式是系統資源分配的單位。程式在處理資料的時候,通過執行緒來完成任務。

#程式相當於一個組織,執行緒就相當於這個組織裡面幹活的員工。程式和執行緒是包含關係,多個執行緒共享程式的空間。

#執行緒在執行的時候的執行順序由作業系統決定

#一顆CPU同時只能執行一件事,他將時間切成很小的時間片,不同的時間片做不同的任務,所以就感覺在同時做多件事情(實際上是輪流執行程式的)。

使用 pstree -p 可以看到系統中的程式和執行緒。#只有一個執行緒後面就不顯示了(後面沒有花括號)。

協程

協程:一個協程就相當於一個函式。

程式、執行緒、協程的區別:

1.執行緒是程式執行的最小單位,程式是作業系統分配資源的最小單位;

2.一個程式由一個或多個執行緒組成,執行緒是一個程式中程式碼的不同執行路線

3.程式之間相互獨立,但同一程式下的各個執行緒之間共享程式的記憶體空間

程式的結構

  • 任務列表

  • PCB

任務列表

任務列表:作業系統允許執行多個程式,程式之間構成了一個程式列表(任務列表),所有程式都放在裡面的。

PCB

PCB:存放一個具體程式的全部資訊(包括程式編號、狀態、優先順序等),因為系統有多個程式,所以就存在多個PCB,每個PCB之間通過指標變數關聯

頁(Page)

頁:程式記憶體資源的分配的最小單位,類似於檔案系統的block,頁的預設大小也是4k

虛擬地址和實體地址

  • 虛擬地址

  • 實體地址

虛擬地址

虛擬地址:存放相對地址,位置是變化的。不是固定的。

應用程式看到的是虛擬地址
實體地址

實體地址:具體的一個固定地址

MMU

MMU:記憶體管理單元(cpu中的硬體晶片),把虛擬地址轉換成實體地址。

程式訪問某個資料的時候,先把請求傳送給作業系統,作業系統再交給cpu,cpu計算為實體地址,然後才能得到真正的資料。
tlb

tlb:快取虛擬地址和實體地址的區域

記憶體的分配空間

  • 使用者空間:程式虛擬記憶體空間

  • 核心空間:作業系統使用的

每個程式都包括5種不同的資料段

  • 程式碼段

  • 資料段

  • BSS段

程式碼段:存放可執行檔案的操作指令

資料段:存放初始化了的全域性變數

BSS段:存放未初始化的全域性變數 #Block Started by Symbol”的縮寫,意為“以符號開始的塊

棧:存放臨時變數(比如函式裡面使用的變數) #先進後出  佇列就是先進先出

堆:存放陣列、物件 

程式使用記憶體問題

  • 記憶體洩漏

  • 記憶體溢位

記憶體洩露: Memory Leak,分配的空間不釋放,一直佔用著

記憶體溢位:Memory Overflow,程式申請的空間不夠用。

記憶體不足:OOM,記憶體不夠用(java中的一種提示)

程式執行的狀態

  • 建立

  • 就緒:

  • 執行

  • 終止

  • 阻塞
    image

使用 ps aux 可以看到程式的狀態
程式更多的狀態:
執行態:running #正在執行

就緒態:ready

睡眠態:程式不幹活了,可中斷:interruptable,不可中斷(不能人為打斷):uninterruptable

停止態:stopped,程式處於暫停的狀態

僵死態:zombie,殭屍態,結束程式,父程式結束前,子程式不關閉,殺死父程式可以關閉僵死

態的子程式(這種程式不佔用空間)

#結束殭屍態的方法:把它的父程式殺死就沒了或者恢復父程式

LRU 演算法

LRU:Least Recently Used 近期最少使用演算法(喜新厭舊),用來實現記憶體的充分利用

IPC 程式之間的通訊

IPC: Inter Process Communication

通訊方法:

  • 同主機

  • 跨主機

同一主機上:

  • 管道

  • 套接字

  • 檔案對映

  • 共享記憶體

  • 訊號

管道:cmd1 | cmd2 (管道符的兩邊就開啟了兩個程式),單工通訊 # | 這屬於匿名管道

#命名管道:建立一個管道(pipe)檔案,用來實現兩個程式之間的通訊。 A--->管道檔案--->B
#建立管道檔案的命令:mkfifo(fifo:先進先出) 
#格式: mkfifo pipe_name


套接字:程式之間雙向通訊
#檢視套接字的方法:find / -type s -ls

檔案對映:檔案的資料對映到記憶體的一塊空間中,多個程式共享這塊記憶體空間

共享記憶體:直接在記憶體中分配一塊空間,這塊空間大家都能使用。

訊號:trap -l 可以檢視。發個訊號程式收到以後就會按照指定的功能來進行操作。

跨主機通訊:

socket:socket就是ip加上埠號。ip地址確定了裝置在網路中的位置。埠號確定了裝置上了具體應用程式。(使用tcp、udp協議都會分配要給與眾不同的獨有埠)

範例

範例:利用管道檔案實現 IPC

mkfifo /data/test.fifo #建立一個管道檔案

ll /data/test.fifo #使用ll檢視管道的資訊,發現它的大小是0位元組,

cat > /data/test.fifo #輸入123456
#在管道檔案裡面寫入資料以後,不會自動退出,且此時檔案的大小依然是0,以為這個管道檔案是在記憶體裡面的,不是在磁碟裡面。

#在另一個終端可以從檔案中讀取資料
cat /data/test.fifo  #會讀取到123456
程式的優先順序
系統優先順序範圍:0-139

0-9:實時優先順序(一些特殊的系統程式)

100-139:非實時優先順序(大部分程式使用的都是這個範圍)

#數字越小,優先順序越高。

CentOS優先順序:
image

nice數字範圍:-20 -- +19  --對應系統優先順序的100-139。 一般程式啟動以後,優先順序使用nice優先順序的0

top顯示的優先順序是0-39,對應系統優先順序的100-139

設定和調整程式優先順序

程式分類

作業系統分類:
  • 協作式多工:

  • 搶佔式多工:

協作式多工:一個任務得到cpu後,只有它主動放棄cpu,其他程式才能使用

搶佔式多工:CPU的控制權由作業系統控制(由作業系統分配cpu資源)
程式型別
  • 守護程式

  • 前臺程式

守護程式:daemon,計算機啟動以後就自動執行,就和終端沒關係了。

前臺程式:跟終端相關,通過終端啟動的程式

程式管理工具

pstree工具:

可以顯示程式之間的父子關係

#格式:
pstree [選項] [pid|user]  #可以檢視指定的程式資訊,也可以檢視所有的程式關係

#選項:
-p:顯示pid

-T:不顯示執行緒

ps工具:

作用:實現程式資訊的檢視,預設顯示當前終端中的程式(顯示的是當前瞬間的狀態)

#ps預設顯示的是當前終端中使用者執行的程式列表。
Linux系統各程式的相關資訊均儲存在/proc/PID目錄下的各檔案中

#格式:
ps [選項]

#三種選項風格:
UNIX選項 如: -A -e  #單個字母

GNU選項 如: --help  #完整單詞

BSD選項 如: a  #只需要一個字母

#常用選項:

a 選項包括所有終端中的程式
u 顯示每個程式是以誰的身份執行等資訊
x 顯示和終端有關或無關的程式(和終端無端:隨計算機啟動就啟動了)
o 屬性… 顯示指定的屬性列 pid、cmd、%cpu、%mem

-e 顯示所有程式,相當於-A
-f 顯示完整格式程式資訊
-p pid 顯示指pid的程式
-t ttylist 指定tty,相當於 t

ps命令的輸出資訊:

C :  ps -ef 顯示列 C 表示cpu利用率

VSZ: 作業系統承諾給程式的空間(虛擬記憶體佔用空間)

RSS: 作業系統實際給程式的空間(實際記憶體佔用空間)

TTY:所在的終端,如果是?號表示和終端無關

STAT:程式狀態
 R:running #正在執行中的
 S: interruptable sleeping #可中斷的睡眠
 D: uninterruptable sleeping #不可中斷睡覺
 T: stopped  #停止
 Z: zombie   #殭屍
 +: 前臺程式
 l: 多執行緒程式
 L:記憶體分頁並帶鎖
 N:低優先順序程式
 <: 高優先順序程式
 s: session leader,會話(子程式)發起者
 I:Idle kernel thread,CentOS 8 新特性

 ni: nice優先順序,nice值 #範圍-20 --- 19 對應:100-139

 pri: priority 系統優先順序數字 #數字越大,優先順序越高

 rtprio: 實時優先順序 #對應系統0-99

 psr: processor 顯示程式和cpu之間的繫結關係 #程式在那顆cpu上執行

範例

#ps -ef  #unix風格
#ps aux #bsd風格
這個風格的選項顯示的資訊沒有aux顯示的要全


##檢視程式的特定屬性
例如:#ps axo pid,cmd,%mem,%cpu

#找到未知程式的執行程式檔案路徑
#ps命令顯示的只是pid和程式的名稱,沒有顯示程式的檔案路徑
ls -l /proc/1272/exe   #1272表示程式的pid  exe是一個軟連線,指向程式的路徑

#範例:檢視優先順序和CPU繫結關係
#ps axo pid,cmd,psr |grep 程式名

prtstat工具:

檢視程式的資訊

#格式
prtstat [選項] pid
例如:#prtstat 1026

[root@Centos8 ~]# prtstat 1026
Process: sshd          		State: S (sleeping)
  CPU#:  1  		TTY: 0:0	Threads: 1
Process, Group and Session IDs
  Process ID: 1026		  Parent ID: 1
    Group ID: 1026		 Session ID: 1026
  T Group ID: -1

Page Faults
  This Process    (minor major):      718         8
  Child Processes (minor major):    80458        11
CPU Times
  This Process    (user system guest blkio):   0.05   0.06   0.00   0.00
  Child processes (user system guest):        93.69  11.96   0.00
Memory
  Vsize:       94 MB
  RSS:         7856 kB    		 RSS Limit: 18446744073709 MB
  Code Start:  0x56188adb7000		 Code Stop:  0x56188ae83f38
  Stack Start: 0x7fffde7c3120
  Stack Pointer (ESP):          0	 Inst Pointer (EIP):          0
Scheduling
  Policy: normal
  Nice:   0 		 RT Priority: 0 (non RT)

檢視某個程式的方法

- ps 選項 | grep 'pattern' #查詢某個程式

- /sbin/pidof 按確切的程式名稱檢視pid

- pgrep工具

pgrep

專門的程式過濾工具

命令格式:
pgrep [options] pattern

# 選項:
-u uid: effective user,程式所有者

-U uid: real user,真正發起執行命令者

-t terminal: 與指定終端相關的程式

-l: 指定程式名 #根據程式名顯示程式資訊

-a: 顯示完整格式的程式名

-P pid: 顯示指定程式的子程式

pidof

知道程式名,用來獲取程式pid。

格式:pidof process _name

#選項:
-x: 查詢指令碼的程式id #指令碼必須shebang機制開頭,以bash的方式來執行找不到,需要加許可權來執行才找得到

uptime

系統負載資訊查詢

#和w命令、top命令最上面顯示的資訊也是一樣的。

#顯示資訊
當前時間

系統已啟動的時間

當前上線人數

系統平均負載(1、5、15分鐘的平均負載,一般不會超過1,超過5時建議警報)

實時程式的檢視:

  • htop工具

  • top工具

top工具

動態實時檢視程式資訊

#選項:
-d # 指定重新整理時間間隔,預設為3秒
-b 全部顯示所有程式
-n # 重新整理多少次後退出
-H   執行緒模式

#top命令顯示的資訊
us:使用者空間
sy:核心空間
ni:調整nice時間
id:空閒
wa:等待IO時間
hi:硬中斷
si:軟中斷(模式切換)
st:虛擬機器偷走的時間

htop工具

top工具的增強版。

#選項;
-d #: 指定延遲時間;
-u UserName: 僅顯示指定使用者的程式
-s COLUME: 以指定欄位進行排序
#子命令
s:跟蹤選定程式的系統呼叫
l:顯示選定程式開啟的檔案列表
a:將選定的程式繫結至某指定CPU核心
t:顯示程式樹

CPU相關資訊顯示:mpstat工具

來源:sysstat包

顯示資訊說明:
CPU:
%usr:使用者空間佔用時間
%nice:nice優先順序
%sys:系統核心佔用時間
%iowait:io等待
%irq:中斷	
%soft:軟中斷
%steal:被虛擬機器執行佔用的時間
%guest:和虛擬化有關的
%gnice:虛擬機器調整優先順序
%idle:空閒的時間


 PID(程式id)
 USER(程式發起者)
 PR(top裡面的優先順序)
 NI(nice優先順序)
 VIRT(虛擬記憶體空間)
 RES(實際記憶體佔用空間)
 SHR(共享記憶體佔用空間)
 S(程式狀態)
 %CPU(cpu利用率)
 %MEM(記憶體)
 TIME+(總的執行時間)
 COMMAND(對應的命令)

記憶體相關資訊檢視

free 可以顯示記憶體空間使用狀態

選項:
-b 以位元組為單位

-m 以MB為單位

-g 以GB為單位

-h 易讀格式

-o 不顯示-/+buffers/cache行

-t   顯示RAM + swap的總和

-s n 重新整理間隔為n秒

-c n 重新整理n次後即退出

快取的清理方法

向/proc/sys/vm/drop_caches中寫入相應的修改值,會清理快取
執行echo 
1、2、3 至 /proc/sys/vm/drop_caches, 達到不同的清理目的

檢視程式開啟檔案 lsof

lsof:list open files,列出正在開啟的檔案。

#選項:
-a:列出開啟檔案存在的程式
-c<程式名>:列出指定程式所開啟的檔案
-g:列出GID號程式詳情
-d<檔案號>:列出佔用該檔案號的程式
+d<目錄>:列出目錄下被開啟的檔案
+D<目錄>:遞迴列出目錄下被開啟的檔案
-n<目錄>:列出使用NFS的檔案
-i<條件>:列出符合條件的程式(4、6、協議、:埠、 @ip )
-p<程式號>:列出指定程式號所開啟的檔案
-u:列出UID號程式詳情
-h:顯示幫助資訊
-v:顯示版本資訊。
-n: 不反向解析網路名字


範例

檢視某個埠是那個程式在使用

#檢視所有正在開啟的檔案:
lsof 

#找回被誤刪除的檔案  前提是這個檔案有人在訪問
1. lsof | grep delete #過濾出被刪除的檔案,找到正在訪問這個檔案的程式編號

2. ll /proc/pid/fd #fd:檔案描述符

3. cat /proc/pid/fd/檔案描述符 > 匯出為新檔案

訊號的管理

kill工具

用來向程式傳送控制訊號,以實現對程式管理,每個訊號對應一個數字,訊號名稱以
SIG開頭(可省略),不區分大小寫

#顯示當前可用的訊號:
trap -l

kill -l

#常用訊號:
1) SIGHUP 無須關閉程式而重新載入配置檔案

2) SIGINT 中止正在執行的程式;相當於Ctrl+c 

3) SIGQUIT 相當於ctrl+\ #退出程式

9) SIGKILL 強行關閉某個程式,可能會導致資料丟失(相當於按電源關機)

15) SIGTERM  正常關閉某個程式,預設訊號

18) SIGCONT 繼續執行

19) SIGSTOP 後臺休眠

#訊號的描述方法
數字法:1, 2, 9

全稱:SIGHUP,sighup

簡稱 去掉開頭的SIG,HUP,hup

#向程式傳送訊號
通過pid的方式:
kill [-s sigspec | -n signum | -sigspec] pid
#-s sigspec:指定完整的訊號名
#-n signum:訊號的數字表示法
#-sigspec:訊號的簡寫方法

#根據程式名傳送訊號
killall 程式名稱

#0訊號
訊號為0,沒有傳送任何訊號,僅僅檢查程式是否正常工作。
格式: killall -0 程式名

例如:
[root@centos8 ~]#killall -0 ping
[root@centos8 ~]#echo $?
0


作業管理

  • 前臺管理

  • 後臺管理

前臺執行管理:

前臺:依賴一個終端,在某個終端執行,啟動以後就佔用這個終端,在這個終端裡面就不能做其他的操作了
例如: ping 127.0.0.1

後臺執行管理

後代:不佔用終端資源,在程式執行的時候加一個&符號

例如:ping 127.0.0.1 &

前後臺執行的切換

預設大多數命令是前臺執行,前後臺是可以切換的。

CTRL+C就是給前臺執行的程式傳送終止訊號,快捷鍵支隊前臺執行的生效。對後臺執行的程式無效。需要使用kill命令來傳送訊號

前--後臺切換方法:

CTRL+Z快捷鍵 --- 把前臺程式放到後臺(放到後臺以後程式就不執行了),通過bg 作業編號 --把後臺停止的作業恢復成後臺執行態
作業編號的查詢:jobs命令
或者 kill -18 %作業編號

後臺執行-->後臺停止:

傳送19訊號: kill -19 %作業編號 作業編號:jobs命令

後--前切換方法;

fg 作業編號

image

後臺執行的作用:

前臺執行都是按照循序執行的,後臺執行可以實現並行執行

後臺執行的任務在終端關閉以後也會隨之關閉。

實現視窗關閉還繼續執行的方法;

方法一:screen命令
程式執行之前開啟screen:格式:screen
然後再輸入要執行的命令

方法二:nohup命令
格式:nohhup 要執行的程式 -- 會有輸出的資訊

並行執行的實現:

並行執行:讓多個程式同時執行

方法一:把他們都放到後臺去執行

方法二:(f1.sh&);(f2.sh&);(f3.sh&) --小括號括起來,分號隔開

方法三:f1.sh&f2.sh&f3.sh&	

範例:掃描ip地址

net=10.0.0
for i in {1..254};do
   { 
    if ping -c1 -W1 $net.$i &> /dev/null;then
        echo $net.$i is up
    else
        echo $net.$i is down
    fi
   }&  #若裡面有多個命令,就用花括號就是把它作為一個整體 
done
wait  #後臺執行的程式結束之後,主動退出

相關文章