1. 程式人生 > 其它 >學習python,從入門到放棄(33)

學習python,從入門到放棄(33)

學習python,從入門到放棄(33)

UDP協議

服務端程式碼:

import socket
server = socket.socket(type=socket.SOCK_DGRAM)  # 自己指定UDP協議(預設是TCP協議)
server.bind(('127.0.0.1', 8080))
msg, addr = server.recvfrom(1024)
print('msg>>>:', msg.decode('utf8'))
print('addr>>>:', addr)
server.sendto(b'hello baby', addr)

客戶端程式碼:

import socket
client = socket.socket(type=socket.SOCK_DGRAM)
server_addr = ('127.0.0.1', 8080)  # 查詢通訊錄
client.sendto(b'hello server baby', server_addr)
msg, addr = client.recvfrom(1024)
print('msg>>>:', msg.decode('utf8'))
print('addr>>>:', addr)

每一次收發資料都需要自己攜帶地址,也會返回資料來源的地址。

基於UDP實現簡易版本的qq

服務端程式碼:

import socket

server = socket.socket(type=socket.SOCK_DGRAM)
server.bind(('127.0.0.1', 8080))
while True:
    msg, addr = server.recvfrom(1024)
    print(addr)
    print(msg.decode('utf8'))
    back_msg = input('請回復訊息>>>:').strip()
    server.sendto(back_msg.encode('utf8'), addr)

各個客戶端程式碼:

import socket

client = socket.socket(type=socket.SOCK_DGRAM)
server_addr = ('127.0.0.1', 8080)

while True:
    msg = input('請輸入想要聊天的內容>>>:').strip()
    msg = '來自客戶端1的訊息:%s' % msg
    client.sendto(msg.encode('utf8'), server_addr)
    msg, addr = client.recvfrom(1024)
    print(msg.decode('utf8'), addr)

所有的客戶端都是一樣的,經過微調在不同的地方使用就是一個個客戶端,可以同時連線到伺服器上。

作業系統的發展史

  1. 穿孔卡片

    形式上,穿孔卡片就是一張紙卡片。這個紙卡片被分為N行M列的格子。IBM的12行80列的穿孔卡片曾是主流。每個格子都可以選擇打孔或不打孔。可以把它想象成一個大小12*80的二維布林陣列。 許多早期的數字計算機使用穿孔卡片作為計算機程式和資料輸入的主要媒介(一個程式可能得用很多張卡片,因為一張卡片通常只表示一行程式碼)。

  2. 聯機批處理系統

    聯機批處理系統,是成批地把輸入機上的使用者作業讀入磁帶,依次把磁帶上的使用者作業讀入主機記憶體並執行並把計算結果向輸出機輸出。完成了上一批作業後,監督程式又從輸入機上輸入另一批作業,儲存在磁帶上,並按上述步驟重複處理。

  3. 離線批處理系統

    離線批處理就是為克服與緩解高速主機與慢速外設的矛盾,提高CPU的利用率,又引入了離線批處理系統,即輸入/輸出脫離主機控制。一般加一臺衛星機,主機不是直接與慢速的輸入/輸出裝置打交道,而是與速度相對較快的磁帶機發生關係,有效緩解了主機與裝置的矛盾。主機與衛星機可並行工作,二者分工明確,可以充分發揮主機的高速計算能力。

作業系統的發展史其實就是提升CPU利用率的過程。

多道技術

多道技術中的多道指的是多個程式,多道技術的實現是為了解決多個程式競爭或者說共享同一個資源(比如cpu)的有序排程問題,解決方式即多路複用,多路複用分為時間上的複用和空間上的複用。

  • 空間上的複用

    將記憶體分為幾部分,每個部分放入一個程式,這樣,同一時間記憶體中就有了多道程式。

  • 時間上的複用

    當一個程式在等待I/O時,另一個程式可以使用cpu,如果記憶體中可以同時存放足夠多的作業,則cpu的利用率可以接近100%,類似於我們小學數學所學的統籌方法。(作業系統採用了多道技術後,可以控制程序的切換,或者說程序之間去爭搶cpu的執行許可權。這種切換不僅會在一個程序遇到io時進行,一個程序佔用cpu時間過長也會切換,或者說被作業系統奪走cpu的執行許可權)

程序理論

程序是計算機中的程式關於某資料集合上的一次執行活動,是系統進行資源分配和排程的基本單位,與程式不同,程式是沒有被 執行的程式碼,程序是正在活動的程式。

為了更加精確的描述出程式的一些實際狀態,才有了程序的概念。

程序排程演算法隨著科技的進步,也跟著一步步發展。

  1. 先來先服務

    在所有排程演算法中,最簡單的是非搶佔式的FCFS演算法。程序按照它們請求CPU的順序使用CPU。就像你買東西去排隊,誰第一個排,誰就先被執行,在它執行的過程中,不會中斷它。當其他人也想進入記憶體被執行,就要排隊等著,如果在執行過程中出現一些事,他現在不想排隊了,下一個排隊的就補上。此時如果他又想排隊了,只能站到隊尾去。

    優點是簡單容易實現,缺點是比較有利於長程序,而不利於短程序。

  2. 短作業優先

    又稱為“短程序優先”SPN;這是對FCFS演算法的改進,其目標是減少平均週轉時間。對預計執行時間短的程序優先分派處理機。通常後來的短程序不搶先正在執行的程序。

    優點是可改善平均週轉時間和平均帶權週轉時間,縮短程序的等待時間,提高系統的吞吐量。缺點是對長程序非常不利,可能長時間得不到執行,且未能依據程序的緊迫程度來劃分執行的優先順序,以及難以準確估計程序的執行時間,從而影響排程效能。

  3. 時間片輪轉法

    該演算法採用剝奪策略。時間片輪轉排程是一種最古老,最簡單,最公平且使用最廣的演算法,又稱RR排程。每個程序被分配一個時間段,稱作它的時間片,即該程序允許執行的時間。

    讓就緒程序以FCFS 的方式按時間片輪流使用CPU 的排程方式,即將系統中所有的就緒程序按照FCFS 原則,排成一個佇列,每次排程時將CPU 分派給隊首程序,讓其執行一個時間片,時間片的長度從幾個ms 到幾百ms。在一個時間片結束時,發生時鐘中斷,排程程式據此暫停當前程序的執行,將其送到就緒佇列的末尾,並通過上下文切換執行當前的隊首程序,程序可以未使用完一個時間片,就出讓CPU(如阻塞)。

    優點是簡單易行、平均響應時間短;缺點是不利於處理緊急作業。

  4. 多級反饋佇列

    多級反饋佇列排程演算法是一種CPU處理機排程演算法,UNIX作業系統採取的便是這種排程演算法。

    一般分為四個步驟:

    1. 程序在進入待排程的佇列等待時,首先進入優先順序最高的Q1等待。
    2. 首先排程優先順序高的佇列中的程序。若高優先順序中佇列中已沒有排程的程序,則排程次優先順序佇列中的程序。例如:Q1,Q2,Q3三個佇列,只有在Q1中沒有程序等待時才去排程Q2,同理,只有Q1,Q2都為空時才會去排程Q3。
    3. 對於同一個佇列中的各個程序,按照時間片輪轉法排程。比如Q1佇列的時間片為N,那麼Q1中的作業在經歷了N個時間片後若還沒有完成,則進入Q2佇列等待,若Q2的時間片用完後作業還不能完成,一直進入下一級佇列,直至完成。
    4. 在低優先順序的佇列中的程序在執行時,又有新到達的作業,那麼在執行完這個時間片後,CPU馬上分配給新到達的作業(搶佔式)。

    優點是兼顧長短作業,有較好的響應時間,可行性強,適用於各種作業環境。

併發與並行

看上去像同時在執行就可以稱之為是併發,讓CPU在多個程式之間利用多道技術來回切換+儲存狀態。

單核肯定能夠實現併發,但是不能實現並行。

必須同一時間同時執行才可以稱之為並行,必須要有多個CPU。

高併發:指併發的極限情況,在程式非常多的時候,CPU還能進行併發時,就是高併發。

高並行:指並行的極限情況,支援非常多個程式同時執行,也就是說有非常多的CPU。

同步與非同步

同步是在提交完任務之後原地等待任務的返回結果,期間不做任何事情。

非同步是指提交完任務之後不願地等待任務的結果,直接去做其他事情 有結果自動提醒。

阻塞與非阻塞

程序有三狀態,就緒態、執行態和阻塞態,他們的關係如圖:

如果想要儘可能的提升程式執行效率,就要想辦法讓我們的程式一直處於就緒態和執行態。

阻塞就是程式處於阻塞態,非阻塞就是程式處於就緒態或執行態。

同步非同步與阻塞非阻塞結合

同步非同步:用來描述任務的提交方式。
阻塞非阻塞:用來描述任務的執行狀態。

同步阻塞是在當核心緩衝區為空時讀資料或者核心緩衝區滿時寫資料,會發生阻塞,這時候執行緒就會阻塞。

同步非阻塞是有請求才建立執行緒,沒有請求時,執行緒就可以做其它的事情。

非同步阻塞相當於去到別的執行緒,讓別的執行緒阻塞起來等待結果,自己不阻塞。

非同步非阻塞相當於去到別的執行緒,別的執行緒一直在執行,直到得出結果。