基礎知識
程式
核心的功能和作用:檔案系統管理、網路管理、程式管理、記憶體管理等,屬於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中的一種提示)
程式執行的狀態
-
建立
-
就緒:
-
執行
-
終止
-
阻塞
使用 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優先順序:
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 作業編號
後臺執行的作用:
前臺執行都是按照循序執行的,後臺執行可以實現並行執行
後臺執行的任務在終端關閉以後也會隨之關閉。
實現視窗關閉還繼續執行的方法;
方法一: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 #後臺執行的程式結束之後,主動退出