##內容回顧python
# UDP協議 用戶數據報協議,是OSI模型中屬於傳輸層的協議 提供,不可靠的,不要求順序的,數據量小的,速度快的傳輸服務 不可靠: 發送完成後不須要確認信息 而且當即刪除緩存中的數據 不要求順序: 當一個數據較大時 會分爲多個數據報來傳輸,對方沒法獲知數據的順序,以及是否完整 數據量較小的: 數據越大丟包的可能性越高 ,建議的數據量不要超過1472 速度快: 相對於TCP而言快不少 不須要確認信息 ,也不須要創建連接 # 通信流程 若是TCP比喻爲手機打電話的過程 那麼UDP能夠看作是對講機 1.買機器 建立UDP的socket 2.固定頻道 bind一個ip和端口 3.收發數據 recvfrom sendto 接收 1.買機器 建立UDP的socket 2.收發數據 recvfrom sendto 注意 不能先收 要收數據 必須明確端口號 沒有端口號是不可能使用網絡服務的 ###TCP 與 UDP 的其餘區別 1.沒有鏈接 2.不會粘包 每次發送都是一個獨立的數據包 TCP 對數據完整性要求較高 : 在線支付 ,文字信息 UDP: 對數據不要求完整性 可是要快 : 視頻 語音 遊戲 # DNS 域名解析服務器 域名 就是一串有規律的字符串 ,用於綁定IP,目的是爲了方便記憶 域名解析服務器 就是幫你將域名轉換爲ip地址 本質就是一個數據庫 裏面存的就是域名和ip對應關係 一臺機器性能有限 分爲 根域名服務器 只存儲定義域名服務器的信息 頂級域名服務器 只存儲二級域名服務器的信息 二級域名服務器 二級存三級 三級域名 三級能夠存四級 一般直接存儲具體的ip信息 ..................... 本地DNS 用於加速解析 ###本身搭建DNS 的做用 1.CDN 內容分發網絡 就是在你的周圍創建更多鏡像服務 2.集羣 # 操做系統 也是一個軟件, 受保護的不能隨意修改 代碼量巨大 內核在500萬以上 長壽 ,一旦完成通常不改 linux是脫襪子 將(shell 保留解釋權!) 移植到minux上 結合產生的 ###操做系統的做用: 1.將複雜醜陋的硬件細節隱藏起來,提供了簡單的調用接口 2.將應用程序對於硬件的競爭變的有序 ###操做系統發展史 1.第一帶計算機 真空管和穿孔卡片 沒有進程 沒有操做系統 2.第二代計算機 7094 1401 晶體管 批處理系統 輸入輸出 以及計算設備 不能互聯 須要人蔘與 一批一批的處理 開發效率慢 而且串行執行 3.第三代計算機 集成電路 與多道技術 多終端聯機 spooling 同一臺機器既能進行科學計算 又能作字符處理 通用計算機 多道技術 解決串行致使的效率低下問題 多用戶終端 能夠同時爲多個用戶提供服務 每一個用戶覺得本身獨享一臺計算機 4.第四代 我的電腦 大規模使用了集成電路,大多都提供了GUI界面 # 多道技術 產生背景 ,全部程序串行 致使資源浪費 目的是讓多個程序能夠併發執行 , 同時處理多個任務 ## 關鍵技術 ### 空間複用 指的是 同一時間 內存中加載多個不一樣程序數據, 每一個進程間內存區域相互隔離,物理層面的隔離 ### 時間複用 切換 + 保存 # 切換條件: 1.一個進程執行過程當中遇到了IO操做 切換到其餘進程 2.運行時間過長,會被操做系統強行剝奪執行權力 單純的切換不夠,必須在切換前保存當前的狀態,以便於恢復執行 # 進程 一個正在被運行的程序就稱之爲進程,是程序具體執行過程,一種抽象概念 進程來自於操做系統
##多進程linux
# 進程和程序的區別 「」「 程序就是一堆計算機能夠識別文件,程序在沒有被運行就是躺在硬盤上的一堆二進制 運行程序時,要從硬盤讀取數據到內存中,CPU從內存讀取指令並執行 , 一旦運行就產生了進程 一個程序能夠屢次執行 產生多個進程,可是進程之間相互獨立 當咱們右鍵運行了一個py文件時 ,其實啓動的是python解釋器,你的py文件實際上是看成參數傳給瞭解釋器 」「」 # 阻塞 非阻塞 並行 併發 (重點) 「」「 #一、阻塞與非阻塞指的是程序的兩種運行狀態
# 阻塞:遇到IO就發生阻塞,程序一旦遇到阻塞操做就會停在原地,而且馬上釋放CPU資源
本地IO input print sleep read write
網絡IO recv send
# 非阻塞(就緒態或運行態):沒有遇到IO操做,或者經過某種手段讓程序即使是遇到IO操做也不會停在原地,執行其餘操做,力求儘量多 併發: 多個任務看起來同時在處理 ,本質上是切換執行 速度很是快 並行: 多個任務真正的同時執行 必須具有多核CPU 纔可能並行 併發 並行 說的是 任務的處理方式 」「」
##進程的三種狀態nginx
#就緒態,運行態,和阻塞態 多道技術會在進程執行時間過長或遇到IO時自動切換其餘進程,意味着IO操做與進程被剝奪CPU執行權都會形成進程沒法繼續執行
##程序員的永恆話題程序員
提升效率
根本方法就是讓程序儘量處於運行狀態
減小IO 儘量多佔用CPU時間
緩衝區就是用於減小IO操做的
##進程的建立和銷燬(瞭解)web
### 進程的建立 但凡是硬件,都須要有操做系統去管理,只要有操做系統,就有進程的概念,就須要有建立進程的方式,一些操做系統只爲一個應用程序設計,好比微波爐中的控制器,一旦啓動微波爐,進程就已經存在。 而對於通用系統(跑不少應用程序),須要有系統運行過程當中建立或撤銷進程的能力,主要分爲4中形式建立新的進程 1. 系統初始化(查看進程linux中用ps命令,windows中用任務管理器,前臺進程負責與用戶交互,後臺運行的進程與用戶無關,運行在後臺而且只在須要時才喚醒的進程,稱爲守護進程,如電子郵件、web頁面、新聞、打印) 2. 一個進程在運行過程當中開啓了子進程(如nginx開啓多進程,os.fork,subprocess.Popen等) 3. 用戶的交互式請求,而建立一個新進程(如用戶雙擊暴風影音) 4. 一個批處理做業的初始化(只在大型機的批處理系統中應用) ### 進程的銷燬 1. 正常退出(自願,如用戶點擊交互式頁面的叉號,或程序執行完畢調用發起系統調用正常退出,在linux中用exit,在windows中用ExitProcess) 2. 出錯退出(自願,python a.py中a.py不存在) 3. 嚴重錯誤(非自願,執行非法指令,如引用不存在的內存,1/0等,能夠捕捉異常,try...except...) 4. 被其餘進程殺死(非自願,如kill -9) ### 進程的層次結構 不管UNIX仍是windows,進程只有一個父進程,不一樣的是: 1. 在UNIX中全部的進程,都是以init進程爲根,組成樹形結構。父子進程共同組成一個進程組,這樣,當從鍵盤發出一個信號時,該信號被送給當前與鍵盤相關的進程組中的全部成員。 2. 在windows中,沒有進程層次的概念,全部的進程都是地位相同的,惟一相似於進程層次的暗示,是在建立進程時,父進程獲得一個特別的令牌(**稱爲句柄**),該句柄能夠用來控制子進程,可是父進程有權把該句柄傳給其餘子進程,這樣就沒有層次了。
##python中實現多進程shell
「」「 在一個應用程序中可能會有多個任務須要併發執行,可是對於操做系統而言,一個進程就是一個任務,CPU會從上往下依次執行代碼,當代碼中遇到IO操做時,操做系統就會剝奪CPU執行權給其餘應用程序,這樣對於當前應用程序而言,效率就下降了,如何使得程序既能完成任務又不下降效率呢?答案就是讓把當前程序中的耗時操做交給子進程來完成,如此當前應用程序能夠繼續執行其餘任務! 」「」 #python中開啓子進程的兩種方式 #方式一:直接實例化Process ,將要執行任務用target傳入 from multiprocessing import Process import os import time # 爲何要子進程 當出現一些耗時較長的操做時 會致使程序進入阻塞狀態 二沒法執行其餘代碼 # 這時候就能夠開啓子進程把任務交給他 def task(name): print(" name %s 子進程run!" % name) # print("son is :%s" % os.getpid()) # print("father is :%s" % os.getppid()) time.sleep(3) print("子進程 over!") if __name__ == '__main__': print("father :%s" % os.getpid()) p = Process(target=task,args=("rose",)) p.start() # 開啓子進程 本質是向操做系統發送請求 讓它啓動進程 一般不可能當即開啓 print("任務結束!") """ windows 和 linux 開啓進程的方式不一樣 首先相同之處都是 須要將數據copy一份給子進程 這樣子進程才知道要幹什麼 linux 會將父進程的全部數據 徹底copy windows 會copy 一部分數據 同時會導入py文件來執行 這樣一來遞歸開進程 linux 拿到父進程知道代碼位置 繼續執行 建議都加上判斷 能夠保證兩個平臺都能用 記住: 開啓進程的代碼 都把它放到 if __name__ == "__main__": 中便可 """ #方式二:繼承Process類 ,覆蓋run方法 將任務放入run方法中 (重點掌握) import os from multiprocessing import Process class MyProcess(Process): def __init__(self,name): super().__init__() self.name = name # 繼承Procee覆蓋run方法將要執行任務發到run中 def run(self): print(self.name) print("子進程 %s running!" % os.getpid()) print("子進程 %s over!" % os.getpid()) if __name__ == '__main__': # 建立時 不用再指定target參數了 p = MyProcess("rose") p.start() print("父進程over!")
##進程間內存相互隔離數據庫
from multiprocessing import Process import time name = "青椒" def task(): global name name = "rose" print("改完了!") print("子進程的%s" % name) if __name__ == '__main__': p = Process(target=task) p.start() time.sleep(2) print(name)
##join函數windows
「」「 調用start函數後的操做就由操做系統來玩了,至於什麼時候開啓進程,進程什麼時候執行,什麼時候結束都與應用程序無關,因此當前進程會繼續往下執行,join函數就能夠是父進程等待子進程結束後繼續執行,即用於提升子進程優先級 ,使得父進程等待子進程結束 」「」 #案例 """ 當你開啓了一個子進程 而且給他一個任務 若是你但願知道這個任務何時完成 那就須要等待 """ import time,os from multiprocessing import Process # def task(i): # # print(" %s 買菸去了" % i) # time.sleep(3) # print("%s 買完了!" % i) # # if __name__ == '__main__': # # p = Process(target=task) # # p.start() # # # time.sleep(5) # # p.join() # 等待子進程執行完畢 將子進程的優先級提升 # # # # # # for i in range(10): # p = Process(target=task,args=(i,)) # p.start() # 進程啓動順序 與start無關 主要看操做系統先切換誰 # # p.join() # # p.join() # 最後一個 # # # print("over!") def task(i): # print(" %s 買菸去了" % i) time.sleep(i) print("%s 買完了!" % i) if __name__ == '__main__': strat_time = time.time() p1 = Process(target=task,args=(1,)) p2 = Process(target=task,args=(2,)) p3 = Process(target=task,args=(3,)) p1.start() p2.start() p3.start() p3.join() #3 p2.join() p1.join() end_time = time.time() print(end_time - strat_time) print("over!")
#案例2
##Process對象經常使用屬性瀏覽器
from multiprocessing import Process import time,os def task(): print("121121") # time.sleep(10) # print("over") # print(os.getppid()) exit(1000) if __name__ == '__main__': p = Process(target=task,name="rose") p.start() # 懶加載優化機制 若是沒有調用start 那麼該對象將不會被建立 time.sleep(1) # p.join() # 等待子進程結束 # p.terminate() # 終止進程 # print(p.name) # 進程的名稱 # print(p.is_alive()) #是否存活 # p.terminate() # 與start同樣 都是給操做系統發送指令 因此會有延遲 # print(p.is_alive()) # print(p.pid) # print(p.exitcode) # 獲取退出碼
##孤兒進程與殭屍進程緩存
## 孤兒進程 指的是,父進程先結束 ,而子進程還在運行着, 孤兒進程無害,有 其存在的必要性 例如:qq開啓了瀏覽器,qq先退出了 瀏覽器應該繼續運行 孤兒進程會被操做系統接管 ## 殭屍進程 值得是,子進程已經結束了,可是操做系統會保存一些進程信息,如PID,運行時間等,此時這個進程就稱之爲殭屍進程 殭屍進程若是太多將會佔用大量的資源,形成系統沒法開啓新新進程 linux 中有一個wai/waitpid 用於父進程回收子進程資源 python會自動回收殭屍進程