1.UDP協議
-稱之為:數據包協議
特點:
1.不需要建立鏈接
2.不需要知道對方是否收到
3.數據不安全
4.傳輸速度快
5.能支持並發
6.不會粘包
優點:
-傳輸速度快
-能支持並發
-不會粘包
缺點:
-數據不安全,容易丟失
應用場景:
早期的qq聊天室:
下面的這個例子,可以先開server或者 client 都是可以的
這個是server的服務端
import socket
# socket.SOCK_DGRAM ---->UPD協議
server = socket.socket(type = socket.SOCK_DGRAM)
#服務端需要綁定一個地址,讓別人知道你在哪里
server.bind(
('127.0.0.1',9002)
)
while True:
data,addr = server.recvfrom(1024)
print(addr)
print(data.decode('utf-8'))
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
這個是client 客戶端
import socket
client = socket.socket(type=socket.SOCK_DGRAM)
address = ('127.0.0.1', 9002)
while True:
msg = input('client---->server:').encode('utf-8')
client.sendto(msg, address)
——TCP協議(稱為:流式協議)
優點:
-數據安全
缺點:
-傳輸的速度慢
-粘包
2.並發編程
2.1操作系統的發展史
1.穿孔卡片
-讀取數據的速度特別慢
-CPU的利用率低
-單用戶(一份代碼)使用
2.批處理
-讀取數據速度特別低
-CPU的利用率低
-聯機(多份代碼)使用
-效率還是低
3.脫機批處理(現代操作系統的設計原理)
-讀取數據的速度高
-CPU的利用率高
2.2多道技術(基於單核背景下處理)
-單道:一條道走到黑-----》串行
-比如:a,b需要使用cpu,a先使用,b等待a 使用完畢后,b才可以使用
優點:程序的執行效率高
缺點:cpu的執行效率低
-多道:
-比如:a,b需要使用cpu,a先使用,b等待a,直到a進入"IO或者執行時間過長",a會(切換+保存狀態),然后b可以使用cpu,等到b執行遇到“IO或者執行時間過長”,再將cpu的權限交給a,直到2個程序結束。
多道的2個特點:
-空間上的復用:
多個程序使用一個CPU
-時間上的復用;
切換+保存狀態
1.當執行遇到IO時,操作系統會把CPU的執行權限剝奪
優點:cpu的執行效率高
2.當執行程序執行時間過長時,操作系統會將cpu的執行權限剝奪。
缺點:程序的執行效率低
2.3並發和並行
-串行:
-並發:
在單核(一個cpu)情況下,當執行2個a,b程序時,a先執行,當a 遇到IO時,b開始爭奪cpu的執行權限,再讓b執行,他們看起來像是同時運行。
-並行:
在多核(多個cpu)的情況下,當執行2個程序時,a和b同時執行,他們是真正意義上的同時運行。
面試問題:在單核情況下能否實現並行? 不行
2.4進程
1.什么是進程?
進程是一個資源單位。
2.進程和程序
-程序:一堆代碼文件
-進程:執行代碼的過程,稱之為進程
-3.進程的調度
1.先來先服務的調度算法
-比如:a,b 若a先來,則讓a先服務,待a服務完畢后,b再服務
-缺點:執行效率低
2.短作業優先調度算法:
-執行時間越短,則優先調度
-缺點:
導致執行時間長的出程序,需要等待所有時間短的程序執行完畢后,才能執行。
3.時間片輪轉法
-比如:同時有10個程序需要執行,操作系統會給你10秒,然后時間片輪法會將10秒分成10等分 分給10個程序,如果有些程序的需要的時間超過1秒,則會繼續排隊,跟下一批的同時程序,按照時間片輪法去分配執行。
4.多級反饋隊列:
1級隊列:優先級最高,先執行隊列中的程序;
2級隊列:優先級以此類推
.....
現代操作系統的進程調度法:時間片輪法+多級反饋隊列
2.5同步和異步
同步與異步指的是”提交任務的方式“
-同步(串行)
2個程序a,b程序都要提交並執行,假如a先提交執行,b必須等a執行完畢后,才能提交任務。
-類似於單道,相當於同步提交任務
-異步(並發)
2個程序a,b程序都要提交並執行,假如a先提交並執行,b不需要等a執行完畢,就可以直接提交任務。
類似於多道,相當於異步提交任務(看來像是同時運行)
-並行
在多核的情況,多個任務同時運行(真正意義上的同時運行)
2.6阻塞和非阻塞
-阻塞(等待)
-凡是遇到io的都會阻塞
IO: input()、 output() 、time.sleep() 、文件的讀寫、 數據的傳輸
-非阻塞(不等待)
除了 IO都是非阻塞,(比如從1+1到100萬)
2.7進程的三種狀態
-就緒態
-同步和異步
-運行態:程序的執行時間過長------->將程序返回給就緒態
-非阻塞
-阻塞態:
-遇到IO
面試題:阻塞和同步是一樣的嗎?非阻塞和異步是一樣的? ----->不一樣
-同步和異步:提交任務的方式
-阻塞和非阻塞:進程的狀態
-異步非阻塞:------>cpu的利用率最大化 ,最大化提高程序的執行效率
2.8創建進程的2種方式
1種 直接調用Process
from multiprocessing import Process
import time
#方式一:直接調用Process
def task():
print(f'start...{1}')
time.sleep(1)
print(f'end...{1}')
if __name__ == '__main__':
obj = Process(target = task)#target 是一個任務》》創建子進程
obj.start()###告訴操作系統去創建一個子進程
print('正在執行當前的進程')###print 這個是主進程,但是有了process
個模塊,新開辟一個名稱空間,放置def task函數的子進程,等主進程節水了,才可以執行子進程
>>>>>>>>>>>>>>>>>>>>>>>>>>>
正在執行當前的進程
start...1
end...1
join()等待子進程結束了,再結束主進程
from multiprocessing import Process
import time
#方式一:直接調用Process
def task():
print(f'start...{1}')
time.sleep(1)
print(f'end...{1}')
if __name__ == '__main__':
obj = Process(target = task)
obj.start()
obj.join()##告訴主進程等待子進程結束后,在結束
print('正在執行當前的進程')
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
start...1
end...1
正在執行當前的進程
#方式一:直接調用Process
def task(name):
print(f'start...{name}')
time.sleep(1)
print(f'end...{name}')
if __name__ == '__main__':
obj1 = Process(target = task,args =('abc',))
obj2 = Process(target = task,args =('def',))
obj3 = Process(target = task,args =('ghk',))
obj1.start()
obj2.start()
obj3.start()
#obj.join()##告訴主進程等待子進程結束后,在結束
print('正在執行當前的進程')
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>####下面這個是異步操作
正在執行當前的進程
start...def
start...ghk
start...abc
end...ghk
end...def
end...abc
加了join的異步提交
from multiprocessing import Process
import time
#方式一:直接調用Process
def task(name):
print(f'start...{name}')
time.sleep(1)
print(f'end...{name}')
if __name__ == '__main__':
obj1 = Process(target = task,args =('abc',))
obj2 = Process(target = task,args =('def',))
obj3 = Process(target = task,args =('ghk',))
obj1.start()
obj2.start()
obj3.start()
obj1.join()##告訴主進程等待子進程結束后,在結束
obj2.join()##告訴主進程等待子進程結束后,在結束
obj3.join()##告訴主進程等待子進程結束后,在結束
print('正在執行當前的進程')
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
start...abc
start...ghk
start...def
end...abc
end...ghk
end...def
正在執行當前的進程
for 循環做的異步
from multiprocessing import Process
import time
#方式一:直接調用Process
def task(name):
print(f'start...{name}')
time.sleep(1)
print(f'end...{name}')
if __name__ == '__main__':
list1 = []
for line in range(10):
obj = Process(target=task, args=('abc',))
obj.start()
list1.append(obj)
for obj in list1:
obj.join()
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
start...abc
start...abc
start...abc
start...abc
start...abc
start...abc
start...abc
start...abc
start...abc
start...abc
end...abc
end...abc
end...abc
end...abc
end...abc
end...abc
end...abc
end...abc
end...abc
end...abc
主進程
第二種的方式
from multiprocessing import Process
import time
class Myprocess(Process):
def run(self):####這個是run是重寫Process內部的方法,只有這樣操作 ,才能執行這個進程
print(f'start...{self.name}的子進程')
time.sleep(2)
print(f'end...{self.name}的子進程')
if __name__ == '__main__':
list1 =[]
for line in range(5):
obj = Myprocess()
obj.start()
list1.append(obj)
for obj in list1:
obj.join()
print('主進程...')
>>>>>>>>>>>>>>>>>>>>>>>>>>>
start...Myprocess-3的子進程
start...Myprocess-4的子進程
start...Myprocess-1的子進程
start...Myprocess-2的子進程
start...Myprocess-5的子進程
end...Myprocess-3的子進程
end...Myprocess-1的子進程
end...Myprocess-2的子進程
end...Myprocess-4的子進程
end...Myprocess-5的子進程
主進程...
主進程...
主進程...
主進程...
主進程...