Linux下文件類型:
bcd -lsp
b(塊、設備文件)
c(字符設備文件)
d(目錄)
-(普通文件)
l(鏈接文件)
s(套接字文件)
p(管道文件)
kill -sig pid:通過pid發送信號殺死指定進程
kill -l:查看操作系統內所所有sig信號
ps -aux ---> STAT表示進程狀態
信號:
SIGHUP 斷開鏈接
SIGINT Ctrl + c
SIGQUIT Ctrl + \
SIGTSTP Ctrl + z
SIGKILL 終止進程且不能被處理
SIGSTOP 暫停進程且不能被處理
SIGALRM 時鍾信號
SIGCHLD 子進程改變狀態時父進程會收到此信號
OSI七層模型 -----> 網絡通信的標准化流程
應用層: 提供用戶服務,具體的內容由特定的程序規定
表示層: 提供數據的加密和壓縮優化
會話層: 確定建立應用鏈接,選擇傳輸服務
傳輸層: 提供數據傳輸服務,進行流量控制
網絡層: 路由選着,網絡互聯
鏈路層: 提供鏈路交換,具體消息的發送
物理層: 物理硬件,接口,網卡的規定
網絡協議:
應用層:TFTP(文件傳輸)、HTTP(超文本傳輸協議)、DNS(域名解析)、SMTP(郵件傳輸)
傳輸層:TCP、UDP
網絡層:IP
物理層:IEEE
IP地址
本地使用:127.0.0.1 或 “localhost”
網絡地址:“0.0.0.0” 或 “172.168.40.53”
IPv4: 點分十進制 例如:192.168.1.3 取值0~255(32位)
IPv6: 128位
socket模塊:
ifconfig:查看本機IP (ens33:本地IP lo:本地回還)
ipconfig:windoes中
socket.gethostname() : 獲取本機主機名
socket.gethostbyname('tedu') : 利用主機名獲取ip
socket.gethostbyname('localhost'): 獲取本地ip
socket.gethostbyaddr('127.0.0.1') 訪問主機IP地址
socket.inet_aton('192.168.1.2') IP十六進制轉換
socket.inet_ntoa(b'\xc0\xa8\x01\02') IP十進制轉換
socket.getservbyname('ssh') 獲取應用程序的端口
創建TCP服務端套接字:
sockfd.socket(sock_family = AF_INET,
sock_tpye = SOCK_STREAM,
proto = 0)
sockfd.bind(addr) 綁定地址
sockfd.listen(n) 設置監聽套接字
connfd,addr = sockfd.accept() 等待接受客戶端鏈接
data = connfd.recv(buffersize) 接收消息
connfd.send(data) 發送消息
sockfd.close() 關閉套接字
創建TCP客戶端套接字:
sockfd.socket(sock_family = AF_INET,
sock_tpye = SOCK_STREAM,
proto = 0)
sockfd.bind(addr) 綁定地址
sockfd.connect(addr) 鏈接服務端
data = connfd.recv(buffersize) 接收消息
connfd.send(data) 發送消息
sockfd.close() 關閉套接字
創建UDP客戶端套接字:
sockfd.socket(sock_family = AF_INET,
sock_tpye = SOCK_DGRAM,
proto = 0)
sockfd.bind(addr) 綁定地址
data = sockfd.recvfrom(buffersize) 接收消息
sockfd.sendto(data, addr) 發送消息
sockfd.close() 關閉套接字
創建UDP客戶端套接字:
sockfd.socket(sock_family = AF_INET,
sock_tpye = SOCK_DGRAM,
proto = 0)
data = sockfd.recvfrom(buffersize) 接收消息
sockfd.sendto(data, addr) 發送消息
sockfd.close() 關閉套接字
創建本地套接字服務端:
sockfd = socket(AF_UNIX, SOCK_STREAM)
sockfd.bind(file) 綁定套接字文件
sockfd.listen(3) 監聽
connfd,addr = sockfd.accept() 等待鏈接
connfd.recv(buffersize) 接收消息
connfd.send(data) 發送消息
sockfd.close() 關閉套接字
創建本地套接字客戶端:
sockfd = socket(AF_UNIX, SOCK_STREAM)
sockfd.connect(sock_file) 鏈接服務端
connfd.recv(buffersize) 接收消息
connfd.send(data) 發送消息
sockfd.close() 關閉套接字
套接字屬性:
sockfd.type 返回套接字類型
sockfd.family 返回地址類型
套接字方法:
sockfd.fileno() 獲取套接字的文件描述符
sockfd.getsockname() 獲取套結字綁定的地址
sockfd.getpeername() 獲取鏈接套接字客戶端的地址
sockfd.setsockopt(level,optname, value) 設置端口可立即重用
sockfd.setblocking(False) 將套接字設置為非阻塞狀態
sockfd.settimeout(sec) 設置套接字的超時時間
select模塊: IO多路復用,阻塞等待監控的IO事件發生
rs, ws, xs = select(rlist, 等待處理的IO
wlist 想要主動處理的IO
xlist[, 出錯希望去處理的IO
timeout]) 超時檢測
p = select.poll 創建poll對象
p.register(s, POLLIN | PLLERR) 注冊關注的IO
events = p.poll() 監控關注的IO事件
multiprocessing模塊: 創建進程對象
Process(target, 要綁定的函數
name, 給進程起的名稱
args, 元組給target函數位置傳參
kwargs) 字典給target函數鍵值傳參
p.start() 啟動進程terget綁定函數
p.join([timeout]) 阻塞等待子進程退出
p.name 獲取進程名(屬性)
p.daemon 設置為True主進程結束殺死所有子進程(必須start()前設置)
p.is_alive() 判斷進程是處於alive狀態(存活)
p.pid 獲取創建進程的pid號(屬性)
pool = pool(x) 創建進程池對象(進程池大小)
pool.apply_async(fun, 要執行的函數(異步執行)
args, 以元組形式為fun傳參
kwds) 以字典形式為fun傳參
pool.apply(fun, args, kwds) (同步執行)
r = pool.map(fun,range(6)) 將要執行的事件放入進程池
pool.close() 關閉進程池
pool.join() 回收進程池
fd1,fd2 = Pipe(duplex=True) 創建管道(Flase:fd1只讀,fd2只寫)
fd.recv() 從管道讀取信息空則阻塞
fd.send(data) 向管道寫入內容滿則阻塞
q = Queue(maxsize=0) 創建隊列對象(存放多少條消息)
q.put(data, 存入消息(支持Python數據類型)
[block, 默認阻塞 False:非阻塞
timeout]) block為True是表示超時檢測
data = q.get([block,timeout]) 取出消息
q.full() 判斷隊列是否為滿
q.empty() 判斷隊列是否為空
q.qsize() 獲取隊列中消息的數量
q.close() 關閉隊列
shm = Value(ctype, 創建共享內存共享空間
obj) ctype字符串:(C語言數據類型),obj初始數據
shm.value 表示共享內存的值(可以賦值)
shm = Array(ctype,obj) 創建共享內存共享空間
sem = Semaphore(num) 創建信號量
sem.acquire() 將信號量減1 0時阻塞
sem.release() 將信號量加1
sem.get_value() 獲取當前信號量的值(數量)
e = Event() 創建Event事件對象
e.wait([timeout]) 阻塞進程 直到事件對象被set
e.set.() 讓事件對象變為被設置狀態
e.clear() 使事件對象清除設置狀態
e.is_set() 判斷當前事件是否被set
Lock = Lock() 創建鎖對象
lock.acquire() 上鎖
lock.release() 解鎖
threading 模塊: 創建線程對象
threshold.Thread(target, 線程函數
name, 線程名字
args, 元組給線程函數位置傳參
kwargs) 字典給線程函數位置傳參
t.start() 啟動線程
t.join() 回收線程
t.name 線程名
t.daemon = True 主線程退出分支線程也退出
t.setDaemon(True) 主線程退出分支線程也退出
t.isDaemon 查看daemon值
t.setName(“name”) 設置線程名稱
t.is_alive() 查看線程狀態
threading.currentThread() 獲取當前進程對象
e = threading.Event() 創建Event事件對象
e.wait([timeout]) 事件阻塞
e.set() 設置事件
e.clear() 清除事件
lock = threading.Lock() 創建鎖對象
lock.acquire() 上鎖
lock.release() 解鎖
socketserver集成並發模塊:
StreamRequestHandler 處理tcp請求
DatagramRequestHandler 處理udp請求
ForkingMixIn 創建多進程
ThreadingMixIn 創建多線程
TCPServer 創建tcp server
UDPServer 創建udp server
ForkingTCPServer ForkingMixIn + TCPServer
ForkingUDPServer ForkingMixIn + UDPServer
ThreadingTCPServer ThreadingMixIn + TCPServer
ThreadingUDPServer ThreadingMixIn + UDPServer
signal模塊:
signal.alarm(sec) 設置時鍾信號給自己SIGALRM信號
signal.pause() 阻塞進程,等待一個信號
signal.signal(sig, 要處理的信號
handler) 處理方法(SIG_DFL:默認 SIG_IGN:忽略 func:自定義函數)
sys模塊補充:
sys.argv 獲取從命令行獲取的參數內容列表
sys.stdin 0 標准輸入IO文件描述符
sys.stdout 1 標准輸出IO文件描述符
sys.stderr 2 錯誤IO文件描述符
sys.exit([status]) 退出一個進程(狀態:退出提示字符串)
字符串方法補充:
S.splitlines 按行分隔
os模塊補充:
os.path.exists(file) 判斷一個文件是否存在
os.remove(file) 刪除文件
os.unlink(file) 刪除文件
pid = os.fork() 創建進程 失敗-1 成功0
os.getpid() 獲取進程的PID號
os.getppid() 獲取父進程的PID
os.exit(status) 退出一個進程(狀態:整數 默認0)
pid,status = os.wait() 塞等待處理子進程的退出
os.WEXITSTATUS(status) 獲取原來退出狀態
pid,status = os.waitpid(pid,option) 阻塞等待處理子進程的退出
os.path.getsize('./1.txt') 讀取文件的大小
os.kill(pid,sig) 發送一個信號給某個進程
os.listdir(path) 獲取指定目錄文件列表
os.path.isfile() 判斷一個 文件是否為普通文件
os.path.isdir() 判斷一個文件是否為目錄
傳輸層服務:
面向連接的傳輸服務(tcp協議):
傳輸特征:
可靠的數據傳輸:
可靠性:無失序、無差錯、無重復、無丟失、無重復
在數據傳輸前和傳輸后需要建立連接和斷開鏈接
面向傳輸服務建立連接的過程:‘三次握手’
1.客戶端向服務器發送鏈接請求
2.服務器接受到請求進行確認,返回確認報文
3.客戶端收到服務器回復最終確認鏈接
面向傳輸服務斷開鏈接的過程:‘四次揮手’
1.主動方發送報文,告知被動方要斷開鏈接
2.被動方回復報文,表示已經接受到請求,准備斷開
3.被動方再次發送報文,表示准備處理就緒,可以斷開
4.主動方發送確認報文,斷開鏈接
應用情況:
適用於傳輸較大的內容或文件,網絡良好,
需要保證傳輸可靠性的情況
e.g. 信息聊天,文件上傳下載,郵件,網頁獲取
面向無連接的傳輸服務(udp協議):
不保證傳輸的可靠性
沒有建立連接和斷開的過程
數據的收發比較自由
適用情況:
網絡情況較差,對可靠性要求不高,收發消息的兩端
e.g.:網絡視頻,群聊,廣播等
收發函數特性:
recv特征:
如果建立的另一端鏈接被斷開, 則recv立即返回空字符串
recv是從接受緩沖區取出內容,當緩沖區為空則阻塞
recv如果一次接受不完緩沖區的內容,下次執行會自動接受
send特征:
如果發送的另一端不存在則會產生pipe...異常
send是從發送緩沖區發送內容當緩沖區為滿則堵塞
http協議:
超文本傳輸協議
用途:
網站中瀏覽區器網頁的獲取,基於網站事物數據傳輸
編寫基於http協議的數據傳輸
特點:
1.應用層協議,傳輸層使用tcp服務
2.簡單、靈活,可以使用多種編程語言操作
3.無狀態的協議,既不用記錄用戶的輸入內容
4.http1.1 ---> http2.0(還沒發布) 技術的成熟和穩定性
http請求(request):
1.請求格式:
1)請求行:說明具體的請求類別和內容
GET /index.html /HTTP/1.1
請求類別 請求內容 協議版本
2)請求類別:
GET:獲取網絡資源
POST:提交一定的附加數據
HEAD:獲取相應頭
PUT:更新服務器資源
DELETE:刪除服務器資源
CONNECT:未使用
TRACE:用於測試
OPTIONS:獲取服務器性能信息
2.請求頭:對請求的具體描述
Accept:text/html
每一個鍵值對占一行,描述了一個特定信息
3.空行
4.請求體:具體的參數或提交的內容
get參數或者post提交的內容
http響應(response):
1.響應格式:
1)響應行:反饋具體的響應情況
HTTP/1.1 20 OK
版本協議 響應碼 附加信息
3)響應碼:
1xx:提示信息,表示請求已經接收
2xx:響應成功
3xx:響應需要定向
4xx:客戶端錯誤
5xx:服務器端錯誤
3)常見響應碼:
200 成功
404 請求內容不存在
401 沒有訪問權限
500 服務器未知錯誤
503 服務器暫時無法執行
2.響應頭:對響應內容的具體描述
3.空行
4.響應體:
將客戶端請求內容進行返回
IO多路復用
定義:
通過一個監測,可以同時監控多個IO事件的行為,
當那個IO可以執行,讓這個IO事件發生
同時監控多個IO事件,當哪個IO事件准備就緒就執行哪個IO事件
此時形成多個IO時間都可以操作的現象,不必逐個等待執行
IO准備就緒:
IO事件即將發生時的臨界狀態是不可逆轉的
在程序中存在的IO事件中選擇要監測的事件
創建監測,將監測的IO事件注冊
等待監測的IO事件發生,判斷是什么事件
處理相應的IO
poll方法實現IO多路復用:
1.創建poll對象:
p = select.poll
2.注冊關注的IO:
p.register(s, POLLIN | PLLERR)
不關注:
p.unregister(s)
事件類別:
POLLIN POLLOUT POLLERR POLLHUP POLLPRI
rlist wlist xlist 斷開 緊急處理
3.監控IO:
events = p.poll()
功能:監控關注的IO事件
返回值:
返回發生IO事件
events是一個列表[(fileno, evnet), (), ()....]
每個就緒IO對應一個元組(描述符,就緒事件)
IO地圖:{s.fileno():s}
4.處理IO事件
位運算:
按照二進制位進行位運算操作
& 按為與 |按位或 ^按位異或
<< 左異 >>右移
11 1011
14 1110
& 1010 有0得0
| 1111 有1得1
^ 0101 相同為0不同為1
11 << 2 == 44 右側補零(乘2乘2次)
14 >> 2 == 3 擠掉右側的數字(地板除2除2次)
使用:
1.在低層硬件時操作寄存器
2.做標志位的過濾
多任務編程:
意義:
充分利用計算機資源,同時運行多個任務,
提高程序整體的運行效率
定義:
通過程序利用計算機的多個核心達到同時執行多個任務的目的
因此達到提升程序運行效率的目的
實施方案:
多進程編程
多線程編程
並行:
多個計算機核心在同時處理多個任務,
這時多個任務之間是並行關系
並發:
同時運行多個任務,內核在多個任務之間的不斷切換,
達到多個任務都會執行的處理效果
此時多個任務之間的並發關系
程序:
是一個可執行文件,是靜態的,只占有磁盤
不占用計算機運行資源
進程:
程序在計算機中的一次執行過程
是一個動態過程,占有一定的計算機資源
有一定的生命周期
注:
同一個程序不同的運行過程是不同的進程,
因為分配的資源和生命周期都不同
進程的創建過程:
1.用戶啟動一個程序,或是調用接口發起進程創建
2.操作系統接收用戶請求分配計算機資源創建進程
3.操作系統將一定狀態的進程提供給用戶使用
4.用戶利用操作提供的進程完成任務
CPU時間片:
如果有個進程占有CPU此時我們稱為該進程占有CPU的時間片
多個進程任務或輪流占有CPU時間片並形成並發效果
進程信息(process)
PCB(進程控制塊):
進程創建后 會自動在內存中產生一個空間存放進程信息
進程信息:
進程ID 進程占有內存的位置 創建時間、創建位置
查看系統進程信息:ps -aux
PID(process ID):
在操作系統中每個進程都有唯一的PID值是由系統分配的
進程特征:
進程是操作系統分配資源的最小單元
每個進程擁有自己獨立的運行空間(4個G的虛擬內存空間)
進程之間相互獨立各不影響
進程的狀態:
三態:
就緒狀態:
進程具備執行條件,等待系統分配處理器資源進入運行態
運行態:
進程占有CPU處於運行狀態
等待態:
進程暫時不具備運行條件,需要阻塞等待
五態:
在三態的基礎上增加新建和終止態
新建:
創建一個新的程序,獲取系統資源的過程
終止:
進程執行結束,釋放資源的過程
ps -aux ---> STAT表示進程狀態:
D 等待態 阻塞 不可中斷等待態
S 等待態 睡眠 可中斷等待態
T 等待態 暫停 暫停執行
R 運行態(就緒態)
Z 僵屍
+ 前台進程(在終端運行)
< 有較高優先級的進程
N 較低優先級的進程
s 回話組
l 有進程鏈接
進程的優先級:
top 查看進程運行態優先級
取值范圍:-20~19 -20最高
nice:
以指定的優先級運行一個程序
nice -9 ./hello.py 以9的優先級運行
sudo nice --9 ./hello.py 以-9優先級運行
首行添加 #! /usr/bin/python3 指定執行器
執行:./hello.py
修改程序權限添加可執行權限
chmod 775 hello.py
孤兒進程 :
當父進程先於子進程退出,此時子進程就會成為孤兒進程。
* 孤兒進程會被系統指定進程收養,即系統進程會成為孤兒
進程新的父進程。系統進程會自動處理孤兒進程退出狀態
僵屍進程 :
子進程先於父進程退出,父進程沒有處理子進程的退出狀態,此時子進程就會成為僵屍進程
* 僵屍進程會滯留部分PCB信息在內存中,大量的僵屍進
程會消耗系統的內存資源,所以要盡量避免僵屍進程產生
如何避免僵屍進程產生?
* 父進程先退出
* 父進程處理子進程退出狀態
* 創建二級子進程
進程池技術:
產生原因:
如果有大量的任務需要多進程完成,而調用周期比較短且需要頻繁創建
此時可能產生大量進程頻繁創建銷毀的情況 消耗計算機資源較大
使用方法:
1.創建進程池,在池內放入適當數量的進程
2.將事件封裝成函數。放入到進程池
3.事件不斷運行,直到所有放入進程池事件運行完成
4.關閉進程池,回收進程
同步互斥機制
目的:
解決對共有資源產生的資源爭奪
臨界資源:
多個進程或線程都可以操作的資源
臨界區:
操作臨界資源的代碼段
同步:
同步是一種合作關系,為完成某個任務,
多進程或者多個線程之間形成的一種協調
按照約定執行,相互告知,共同完成任務
互斥:
互斥是一種制約關系,當一個進程或者線程
進入臨界區操作資源時采用上鎖的方式,
阻止其他進程操作,直到解鎖后才能讓出資源
多線程:
什么是線程(thread)?
線程也是一種多任務編程方式,可以使用計算機的多核資源
線程被稱為輕量級的進程
線程的特征:
1.一個進程可以包含多個線程
2.線程是計算機內核使用的最小單位
3.線程也是一個運行過程,也要消耗計算機資源
4.多個線程共享共用進程的資源
5.線程也有自己的特征屬性,TID、指令集、線程棧
6.多個線程之間獨立運行互不干擾 空間不獨立(都消耗進程空間)
7.線程的創建刪除消耗的資源要小於進程 線程/進程(1/20)
線程通信:
多個線程共用線程空間,所以進程的全局變量對進程內線程均可見
線程的通信方法就是使用去全局變量通信
注:
線程間使用全局變量進程通信時,全局變量為共享資源
往往需要同步互斥機制
進程和線程的區別和聯系:
1.兩者都是多任務編程的方式 都能夠使用計算機的多核
2.進程的創建和刪除要比線程消耗更多的計算機資源
3.進程空間獨立,數據安全性好,有專門的進程間的通信方法
4.線程使用全局變量,更加簡單,但需要同步互斥操作
5.一個進程可以包含多個線程,線程共享進程空間資源
6.進程線程都獨立執行,有自己的特有屬性
使用情況:
1.一個進程中並發任務比較多,比較簡單,適合使用多線程
2.如果數據程序比較復雜,特別是可能多個任務通信比較多的時候
要考慮使用線程同步互斥的復雜性
3.多個任務存在明顯差異,和功能分離的時候沒有必要一定寫入到一個進程中
4.使用Python要考慮到GIL的問題
Pyhthon線程GIL問題:
GIL (全局解釋器鎖)
Python --->支持線程操作--->出現IO同步互斥--->加鎖--->超級鎖,給解釋器加鎖
后果:
同一時刻一個解釋器只解釋一個線程
此時其他線程需要等待。大大降低了Python線程的執行效率
只能實現並發不能實現並行
Python GIL問題解決方案:
1.修改c解釋器
2.盡量使用多進程進行並行操作
3.Python線程盡量用在高延遲多阻塞的IO情形
3.不使用CPython 使用C#、JAVA 做的得解釋器
網絡服務器基礎:
循環服務器::
單進程程序,循環接受客戶請求,處理請求,處理完畢后再接受下一次請求
特點:
每次只能處理一個客戶端請求,如果客戶端長期占有服務器則無法處理其他客戶端
請求
優點:
實現簡單,占用資源少
缺點:
無法同時處理多個客戶端,體驗差
使用情況:
任務短暫,可以快速完成,udp比tcp更適合循環
並發服務器:
能夠同時處理多個客戶端任務請求
IO並發:
IO多路復用 協程
優點:
可以實現IO並發操作,占用系統資源少
缺點:
不能夠監控CPU密集的情況,並不能有長期阻塞
多進程/線程並發:
為每個客戶端單獨提供一個進程或線程,處理客戶端請求
優點:
客戶端可以長期占有服務器
缺點:
消耗計算機資源比較多