網絡編程+併發編程總結

網絡編程+併發編程

架構:B/S 和 C/S
	C/S:充分發揮PC機的性能
	B/S:統一了應用的接口,隸屬於CS架構
	
	
OSI模型  七層:表示層,會話層,應用層,傳輸層,網絡層,數據鏈路層,物理層。
咱們用五層

應用層	http協議   https協議   ftp協議  snmp/pop3/stmp/dns
傳輸層	tcp udp 協議	(四層交換機)
網絡層	IP協議/icmp協議	路由器	(三層交換機)
數據鏈路層	arp協議,交換機  (二層交換機)
物理層	網卡,雙絞線     (傳輸電信號)
arp/rarp
  Arp協議(地址解析協議):經過目標ip地址獲取目標mac地址    arp涉及到的物理設備:二層交換機  rarp:經過mac地址找ip地址
物理地址:mac地址全球惟一,每一個電腦的網卡上
Ip地址:  四位點分十進制			三十二位點分二進制ipv4/ipv6  : 4位點分十進制,6爲冒分16進制

交換機的通訊方式:
	單播:點對點
	組播:點對多
	廣播:向多個pc端發送數據包

交換機和路由器的區別?
交換機是組織局域網的,通過內部處理解析數據,將數據已點對點,點對多的方式發送給目標
路由器是跨網段的數據傳輸,路由出網絡傳輸的最佳路徑



 socket 介於應用層和傳輸層的socket抽象層


Tcp:  可靠、面向鏈接的雙全工通訊 無邊界的字節流 慢 佔用系統中的鏈接資源  1 全雙工的  面向字節流的(無邊界的字節流,多條tcp數據之間沒有邊界)  2 可靠,不是不安全,更多的是保證數據的網址性  3 (面相連接,必需要先創建鏈接再進行同窗)三次握手,四次揮手   4 慢:通訊  創建/斷開鏈接 保證數據的完整性的機制  5 佔用系統資源(核心要解決的問題)    在不使用任何異步機制(進程/線程/協程),在阻塞io模型中,一個server端只能和一個client端相連    conn1,conn2,conn3    sk = socket.socket()    sk.setblocking(False) # 異步的概念    conn_lst = []    try:      conn,addr = sk.accept()      conn_lst.append(conn)    except BlockingIOError:      for conn in conn_lst:        try:          conn1.recv()  # 有數據在緩存裏面就接收,沒有數據就報錯        except BlockingIOError:pass
Udp:  無鏈接的,面向數據報,面向數據報的,不可靠,速度快,能傳輸的數據長度有限。能夠同時和多個客戶端通訊  不會粘包、速度快、能夠和任意多個客戶端進行互相通訊  容易丟失數據、傳輸的數據長度有限
  
三次握手:(必須是客戶點先發起)
1.客戶端發起SYN請求連接服務端          
2.服務端收到請求,向客戶端發送能夠鏈接的請求     ACK
3.客服端收到鏈接,鏈接成功            ACK


四次揮手:(客戶端和服務端均可以發起)

1.客戶端發起斷開鏈接的FIN請求
2.服務端收到請求,而後準備斷開鏈接的一些事物
3.服務端發送請求,我已經準備完畢,能夠斷開了
4.客戶端收到請求,斷開鏈接。
爲何揮手是四次?   當我仍然有數據發送的時候,還能夠發送!
爲何會發生黏包:由於有緩存機制,連續發或者連續收。(在數據傳輸過程當中,接收數據端接收數據時不知道該如何接收,形成的數據混亂現象)
合包機制:nagle算法 — 發數據的時候一點一點發,可是接收的時候會一次收到。 
拆包機制:發送的數據太大,分開發送,接收的時候,最後不能剛剛接完,就會發生黏包。
都是發生在發送端。 全部的數據都會在接收端的緩存區中被合在一塊兒,若是沒有及時獲取信息,那麼消息會粘在一塊兒。
發生在接收端
如何解決黏包?

自定義表頭:用struct模塊,事先將要發送文件的大小存下來,發送 過去,而後按着指定數據開始接收。
Struct 模塊  能夠將一個整數,封裝爲一個指定(通常爲4)字節數的數字,這樣接收端就能夠指定大小接收這個數字。

各類網絡設備  傳輸層    四次防火牆/四層防火牆/四層交換機  網絡層    路由器  防火牆 三層交換機  數據鏈路層  交換機 網卡  物理層    網線
socketserver(threading/socket/selector)  幫助你完成server端的併發效果模塊socket在應用層和傳輸層之間,socket是一組封裝了後四層協議數據拼接的接口。

操做系統

Dos系統			#單用戶單任務
Windows系統		#單用戶多任務(早起的Windows)
Unix系統			#多用戶多任務

操做系統的做用:1)封裝接口,讓用戶方便使用 	2)對系統資源的分配與調度

計算機的五大組成部分:運算器。控制器。存儲器。輸入設備。輸出設備。

編程語言發展史:機器語言,彙編語言,高級語言

並行:(兩件事或者多件事)同一時間點,同時執行 (多個CPU)
併發:(兩件事或者多件事)同一時間間隔,交替執行
阻塞:程序由於相似IO等待、等待時間等致使沒法繼續執行
非阻塞:程序遇到相似於IO操做時,再也不阻塞等待,若是沒有及時的處理IO,就會報錯或者跳過等待其餘操做,
同步:某一個任務的執行必須依賴另外一個任務的返回結果  -任務(當前所在的代碼和另外一個獨立的任務)
異步:一個任務的執行,不須要依賴另外一個任務的返回,只須要告訴另外一個任務一聲
### p.start() 只是向操做系統發了一個啓動的命令,至於操做系統何時啓動我無論,這就是一個典型的異步非阻塞
進程:cpu資源分配的最小單位    	進程由三部分組成:代碼段,數據段,PCB(進程控制塊)  資源獨立,能利用多核,佔用操做系統的資源大,有數據安全問題
線程:cpu資源調度的最小單位		線程由三部分組成:代碼段,數據段,TCB(線程控制塊)
  資源共享,能利用多核,佔用操做系統的資源相對少,有數據安全問題  協程:操做系統不可見  資源共享,不能利用多核,本質是一條線程,佔用操做系統的資源就 至關於一條線程,不存在數據安全問題進程:  資源獨立線程  處理併發   (同時處理多個任務)GIL鎖 CPython解釋器中管理線程的機制  保證多個線程,只有一個線程在同一時間點能訪問cpu  CPython解釋器致使了咱們不能充分利用多線程來訪問多個cpu  多進程:幫助咱們Cpython解釋器下利用多核協程  在單線程中,有n個任務,這n個任務若是是同步執行,那麼全部的io時間是累加在一塊兒的        若是這n個任務可以共享全部的io時間  完成一個任務,遇到io以後可以切換到另外一個任務執行,全部的io操做的時間還能作其餘任務的執行    這樣就能經過一條線程完成多個任務。    協程:切換也是有開銷的,切換的開銷就和函數調用的開銷是同樣的。      asyncio    內置的異步模塊 (進程、線程、協程)    gevent     擴展的協程模塊    aiohttp   擴展模塊  幫助咱們利用協程完成http請求的模塊數據安全  多個進程操做一個文件,加鎖  多個線程操做一個全局變量,加鎖    若是是+=   *=  /=  -=  都存在數據不安全的問題    append remove  pop extend 不存在數據不安全的問題  協程 永遠不會數據不安全,由於協程是由程序員控制的,而程序員控制的只能是代碼,而不是CPU指令      import dis      dis.dis()  # 查看CPU指令  
進程的三大基本狀態:
	就緒狀態:已經得到運行所需的全部資源,除CPU
	執行狀態:已經得到全部資源包括CPU,處於正在運行
	阻塞狀態:由於各類緣由,進程放棄了CPU,致使進程沒法繼續執行,此時進程處於內存中,繼續等待獲取CPU的一種狀態。ß

進程學的東西: multiprocessing

1)Process模塊
	線程的建立 	
	1)直接建立
	p = Process(target = func, args = (元組形式, 爲func所傳的參數)) #實例化進程對象	
	2)繼承 (Process)

	多線程的開啓	1)for循環		2)多個對象實例化
	方法:
		start()		#開啓進程
		join()			#感知進程的結束,異步變同步
		is_alive()		#判斷進程是否存活
		terminate()	#殺死一個進程
	屬性:
		name			#獲取進程名
		pid				#獲取進程號
		daemon = True 	#守護進程    
		守護進程的特色:
			#當主進程代碼結束後,守護進程隨主進程結束
			#守護進程不能再建立子進程
			#守護進程必須在start以前			

2)	鎖  		Lock模塊			(互斥鎖/同步鎖)  只能acquire一次
		lock = Lock()	#實例化一個鎖對象
		lock.acquire()	#上鎖
		lock.release()	#解鎖
			RLock模塊		(遞歸鎖)
		遞歸鎖能夠同時acquire屢次,可是必須acquire幾回就必須release幾回。都在就會陷入死鎖狀態
			死鎖
		典型的例子:科學家吃麪    (一我的拿着面,一我的拿着叉子,到最後誰也吃不上面)

	信號量	Semaphore模塊
		sem = Semaphore(int數據類型)	#能夠指定有多少線程能夠同時拿到鎖
		sem.acquire()					#須要上鎖將這些數據鎖住
		sem.release()
	事件		Event模塊
		e = Event()
		e.wait()	#根據is_set()的狀態來決定,自身的阻塞狀態  若是is_set()爲False則爲阻塞,若是is_set()爲True則爲非阻塞
		e.is_set()		#默認爲False,
		e.set()		#將is_set()的狀態變爲True
		e.clear()		#將is_set()的狀態變爲False

	典型例子:紅綠燈事件	

3)進程間通訊(IPC)
	Queue模塊		#隊列     先進先出    First in first out
		q = Queue()	#建立隊列對象(能夠指定大小)
		q.put() 		#向隊列中添加元素(若是隊列以滿處於阻塞狀態,只有當隊列不滿才能夠繼續添加)
		q.get()		#取出隊列中元素(若是隊列中元素爲空處於阻塞狀態,只有對列中有元素才能夠繼續取出)
		q.full()		#判斷一個對列是否 已滿
		q.empty()		#判斷一個對列是否爲空
		q.put_nowait()	 #不阻塞,若是能夠繼續往隊列中放數據就繼續放,不能放就報錯
		q.get_nowait()	 #不阻塞,若是有數據就直接獲取,沒有數據就報錯
	JoinableQueue()模塊
		q = JoinableQueue()
						#繼承了Queue模塊,可是新增了兩個方法
		q.task_done()   	#統計對列q有多少個元素被拿走(拿走一個數據就給join返回一個結果),一般與q.get()在一塊兒用  用於生產者
		q.join()			#感知一個對列的數據被所有執行完畢  與q.put()在一塊兒用      用於消費着
	
	隊列  =  管道  +  鎖
		
	重點:生產者消費着模型  應用場景:爬蟲/高併發的web程序server
		
	Pipe模塊			#管道   (自己是不安全的)         (雙全工)
		p = Pipe()
		conn1, conn2  = Pipe()
	
		管道是不安全的
		管道是用於多進程之間通訊的一種方式
		若是在單進程中使用管道,那麼就是conn1收數據,conn2發數據
							若是是conn1發數據,那麼conn2收數據
		若是在多進程中使用管道,那麼就必須是父進程中用con1收,子進程中使用conn2發
									父進程使用conn1發,子進程中使用conn2收
									父進程使用conn2收,子進程中使用conn1發
									父進程使用conn2發,子進程中使用conn1收
		在管道中有一個著名的錯誤叫作EOFERrror。
		是指:父進程中若是關閉了發送端,子進程還繼續接受數據,那麼就會引起EOFError

4)數據共享	Manager模塊    Value模塊
	men = Manager()
	(1)
	m.list(列表數據)
	m.dict(字典數據)
	(2)
	with Manager() as m:
		……

5)進程池		Pool模塊

	p = Pool(os.cup_count() +1)		#開啓多進程以後,每次處理數據只能指定個數個處理
	
	p.close()
	p.join()	#close在join以前

	方法:
		map(func, itreable)	#異步處理 itreable ,有返回值,返回值是,每個func的返回值組成的列表, 自帶close和join
		apply(func, args)	#同步處理		有返回值,返回值爲func的返回值   不須要加close和join
		apply_async(func, args, callback)	#異步處理,有返回值,返回一個對象,這個對象有get方法,能夠獲取func的返回值
									#這個get只能一個一個獲取,以咱們通常處理完全部線程後再獲取數據
									#func的返回值能夠做爲參數傳給callback這個回調函數。回調函數在主進程中執行
		apply函數中的全部進程都爲普通進程
		apply_async函數中的全部進程都爲守護進程




線程學的東西:threading

GIL:全局解釋器鎖(只有CPython纔有)
	鎖的是線程:同一時間只容許一個線程訪問CPU      #(沒有真正的並行)

1)Thread模塊

	線程的建立
	1)t = Thresd(target= func. args = (元組,爲func所傳的參數))   實例化線程對象
	2)繼承
	
	多線程的建立
	1)for 循環
	2)直接實例化多個對象

2)	鎖
		Lock		#互斥鎖(同步鎖)
		RLock 	#遞歸鎖
		死鎖		#死鎖
	 
	信號量	Semaphore模塊
		sem = Semaphore(int數據類型)	#能夠指定有多少線程能夠同時拿到鎖
		sem.acquire()					#須要上鎖將這些數據鎖住
		sem.release()

	事件		Event模塊
		e = Event()
		e.wait()	#根據is_set()的狀態來決定,自身的阻塞狀態  若是is_set()爲False則爲阻塞,若是is_set()爲True則爲非阻塞
		e.is_set()		#默認爲False,
		e.set()		#將is_set()的狀態變爲True
		e.clear()		#將is_set()的狀態變爲False

3)條件	Condition模塊
	
		條件是讓程序員自行去調度線程的一個機制
		
		方法:
		acquire()
		release()
		wait()   #讓線程阻塞住
		notify(int數據類型)	#是指給wait發一個信號,讓wait變成不阻塞						#int數據類型,是指你要給多少wai發信號
	

4)定時器		Timer模塊

		建立:Timer(time, func)
				#time:睡眠時間,以秒爲單位
				#func:睡眠以後,須要執行的任務
		

5)線程池


進程與線程的區別:
	進程資源分配的基本單位,線程是cpu調度的基本單位。
	線程不能夠本身獨立擁有資源。線程的執行,必須依賴於所屬進程中的資源。
	進程中必須至少應該有一個線程。

線程和進程的比較:
	1)cpu切換進程比切換線程慢不少,在python中若是IO操做過多的話,使用線程最好
	2)在同一個進程內,全部線程共享這個進程pid,也就是說全部線程共享所屬進程的全部資源和內存地址
	3)在同一個進程內,全部線程共享該進程中的全局變量
	4)由於GIL鎖的存在,在CPython中,沒有真正的線程並行。可是有真正的多進程並行
		當你的任務是計算密集的狀況下,使用多進程好。
		總結:在CPython中,IO密集用多線程,計算密集用多線程。
	5)關於守護線程和守護進程的事情:(注意:代碼執行結束,並不表明程序結束)
		守護進程:要麼本身正常結束,要麼根據父進程的代碼執行結束而結束
		守護線程:要麼本身正常結束,要麼根據父線程的執行結束而結束(會等其他子線程運行結束)
相關文章
相關標籤/搜索