Python 模塊(八) socketserver 以及 線程、進程


目錄

  • 異常處理
  • socketserver
  • 線程、進程

一、異常處理


try的工作原理是,當開始一個try語句后,python就在當前程序的上下文中作標記,這樣當異常出現時就可以回到這里,try子句先執行,接下來會發生什么依賴於執行時是否出現異常。
代碼示例:

while True:
    n1 = input('input a number: ')
    n2 = input('input a number: ')



    try:
        n1 = int(n1)
        n2 = int(n2)
        res = n1 + n2
        print(res.sd)
        l = [1,2,3,4,]
        print(l[10])

        d = {1:'a',2:'b'}
        print(d[3])
        print('num:%s' %res)
    except ArithmeticError as e:    #引用屬性錯誤
        print('ArithmeticError')
    except IndexError as e:        #下標錯誤
        print('IndexError')
    except KeyError as e:        #key錯誤
        print('KeyError')
    except ValueError as e:        #引用的值錯誤
        print('ValueError',e)
    except Exception as e:        #拋出絕大部分的錯誤
        print('異常錯誤')
        print(e)

 


通過創建一個新的異常類,程序可以命名它們自己的異常。異常應該是典型的繼承自Exception類,通過直接或間接的方式。

#自定義異常
class DemoException(Exception):
    def __init__(self,msg):
        self.message = msg
    def __str__(self):
        return self.message
a = 1
try:
    #如果不滿足該條件,拋出異常
    assert a == 1
except DemoException as e:
    print(e)
else:
    print('ok')
#無論是否存在異常,都執行finally
finally:
    print('over')

二、sokectserver


socketserver 是標准庫中一個高級別的模塊,用於簡化網絡客戶與服務器的實現。
1、要實現本模塊,必須定義一個繼承於基類BaseRequestHandler的處理程序類。BaseRequestHandler類的實例可以實現以下方法:
    1、h.handle() 調用該方法執行實際的請求操作。調用該函數可以不帶任何參數,但是幾個實例變量包含有用的值。h.request包含請求,h.client_address包含客戶端地址,h.server包含調用處理程序的實例。對TCP之類的數據流服務,h.request屬性是套接字對象。對於數據報服務,它是包含收到數據的字節字符串。
    2.h.setup()該方法在handle()之前調用。默認情況下,它不執行任何操作。如果希望服務器實現更多連接設置,可以在這里實現。
    3.h.finish()調用本方法可以在執行完handle()之后執行清除操作。如果setup()和 handle()都不生成異常,則無需調用該方法。
2.服務器。要使用處理程序,必須將其插入到服務器對象。定義了四個基本的服務器類。
    1、TCPServer 支持ipv4的TCP協議的服務器。
    2、UDPServer 支持ipv4的UDP協議的服務器。
    3、UnixStreamServer 使用UNIX域套接字實現面向數據流協議的服務器,集成自TCPserver。
    4、UnixDatagramServer 繼承自UDPServer

    四個服務器類的實例都有一下方法和變量:
    1、s.socket 用於傳入請求的套接字對象
    2、s.server_address 監聽服務器的地址
    3、s.RequestHandleClass 傳遞給服務器構造函數並由用戶提供的請求處理程序類
    4、s.server_forever() 處理無線的請求
    5、s.shutdown() 停止server_forever()循環
    6、s.fileno() 返回服務器套接字的整數文件描述符。該方法可以有效的通過輪詢操作實例

代碼實例

server端
#導入該模塊
import socketserver

#定義一個類,繼承socketserver.BaseRequestHandler
class Server(socketserver.BaseRequestHandler):
    def handle(self):
    #打印客戶端地址和端口
        print('New connection:',self.client_address)
    #循環
        while True:
        #接收客戶發送的數據
            data = self.request.recv(1024)
            if not data:break#如果接收數據為空就跳出,否則打印
            print('Client data:',data.decode())
            self.request.send(data)#將收到的信息再發送給客戶端

if __name__ == '__main__’:
    host,port = '127.0.0.1’,8080  #定義服務器地址和端口
    server = socketserver.ThreadingTCPServer((host,port),Server) #實現了多線程的socket通話
    server.serve_forever()#不會出現在一個客戶端結束后,當前服務器端就會關閉或者報錯,而是繼續運行,與其他的客戶端繼續進行通話。

client端
import socket
ip_port = ('127.0.0.1',8080)
sk = socket.socket()
sk.connect(ip_port)

while True:
    raw = input('>> ').strip()
    sk.send(bytes(raw,'utf8'))
    msg = sk.recv(1024)
    print(str(msg,'utf8'))
sk.close()

 


三、進程和線程



1、定義
進程是具有一定獨立功能的程序,關於某個數據集合上的一次運行活動。進程是系統進行資源分配和調度的一個獨立單位。
線程是進程的一個實體,是CPU調度和分配的基本單位,它是比進程更小的能夠獨立運行的基本單位。線程不擁有系統資源,但是可以和同屬一個進程的其他線程貢獻進程所擁有的全部資源。
2、關系
一個線程可以創建和銷毀另一個線程;同一個進程中的多個線程之間可以並發執行。
3、最大差別在於它們是不同的資源管理方式。進程有獨立的地址空間,一個進程崩潰后,不會對其它進程產生影響,而線程只是一個進程中的不同執行路徑。線程有自己的堆棧和局部變量,但沒有單獨的地址空間。因此一個線程死掉等於整個進程死掉,多以多進程的程序要比多線程的程序強壯,但進程切換時耗費資源比較大。對於一些要求同事進行又要共享某些變量的並發操作,只能用線程,不能用進程。
Python threading模塊
threading提供了一個比thread模塊更高層的API來提供線程的並發性。這些線程並發運行並共享內存。
 一、Thread的使用
    目標函數可以實例化一個Thread對象,每個Thread對象代表着一個線程,可以通過start()方法,開始運行。
    有兩種方式來創建線程:一種是通過繼承Thread類,重寫它的run方法;另一種是創建一個threading.Thread對象,在它的初始化函數(__init__)中將可調用對象作為參數傳入。

import threading
import time

def sayhi(num):
    print('running on nuber:%s' %num)
    time.sleep(3)

if __name__ == '__main__':

    t1 = threading.Thread(target=sayhi,args=(1,))
    t2 = threading.Thread(target=sayhi,args=(2,))

    t1.start()
    t2.start()

    print(t1.getName())
    print(t2.getName())
import threading
import time

def sayhi(num):
    print('running on nuber:%s' %num)
    time.sleep(3)

if __name__ == '__main__’:
    t_list = []
    for i in range(20):
        t = threading.Thread(target=sayhi,args=[i,])
            t.start()
            t_list.append(t)
    for i in t_list:
        i.join()
    print('----done——')

 


threading模塊中的join函數
該函數的作用主要是阻塞進程直到線程執行完畢。通用的做法是啟動一批線程,最后join這些線程結束。
原理就是一次檢驗線程池中的線程是否結束,沒有結束就阻塞知道線程結束,如果結束則跳轉執行下一個線程的join函數。




end


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM