Python 多執行緒套接字程式設計?
多執行緒概念
多執行緒是幾乎所有現代程式語言的核心概念,特別是 Python,因為它實現了簡單的執行緒。
執行緒是程式中的一個子程式,可以獨立於程式碼的其他部分執行。執行緒在相同的上下文中執行,共享程式的可執行資源,例如記憶體。
當在單個程序中,我們同時執行多個執行緒時,這稱為多執行緒。
Python 多執行緒模組用於執行緒實現
為了在程式中實現執行緒,Python 提供了兩個模組:
- thread(適用於 Python 2.x)或 _thread(適用於 Python 3.x)模組
- threading 模組
其中 thread 模組將執行緒建立為函式,而 threading 模組提供了一種面向物件的方法來建立執行緒。
語法
_thread.start_new_thread(func, args[, kwargs])
以上程式碼啟動了一個新執行緒並返回其識別符號。第一個引數是函式 func,執行緒使用第二個引數執行,第二個引數包含一個元組,其中包含引數的位置列表。可選的 kwargs 引數指定一個關鍵字引數字典。當函式返回時,執行緒會靜默退出。
在這裡,我們看到了一個客戶端-伺服器應用程式的基本示例。客戶端基本上開啟套接字連線並將查詢傳送到伺服器。伺服器進行響應。
在沒有引數的情況下執行時,此程式將啟動一個 TCP 套接字伺服器,該伺服器偵聽 127.0.0.1 上埠 8000 的連線。
client_thread1.py
import socket
import sys
def main():
soc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = "127.0.0.1"
port = 8000
try:
soc.connect((host, port))
except:
print("Connection Error")
sys.exit()
print("Please enter 'quit' to exit")
message = input(" -> ")
while message != 'quit':
soc.sendall(message.encode("utf8"))
if soc.recv(5120).decode("utf8") == "-":
pass # null operation
message = input(" -> ")
soc.send(b'--quit--')
if __name__ == "__main__":
main()而伺服器程式是:
server_thread1.py
import socket
import sys
import traceback
from threading import Thread
def main():
start_server()
def start_server():
host = "127.0.0.1"
port = 8000 # arbitrary non-privileged port
soc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
soc.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
print("Socket created")
try:
soc.bind((host, port))
except:
print("Bind failed. Error : " + str(sys.exc_info()))
sys.exit()
soc.listen(6) # queue up to 6 requests
print("Socket now listening")
# infinite loop- do not reset for every requests
while True:
connection, address = soc.accept()
ip, port = str(address[0]), str(address[1])
print("Connected with " + ip + ":" + port)
try:
Thread(target=client_thread, args=(connection, ip, port)).start()
except:
print("Thread did not start.")
traceback.print_exc()
soc.close()
def clientThread(connection, ip, port, max_buffer_size = 5120):
is_active = True
while is_active:
client_input = receive_input(connection, max_buffer_size)
if "--QUIT--" in client_input:
print("Client is requesting to quit")
connection.close()
print("Connection " + ip + ":" + port + " closed")
is_active = False
else:
print("Processed result: {}".format(client_input))
connection.sendall("-".encode("utf8"))
def receive_input(connection, max_buffer_size):
client_input = connection.recv(max_buffer_size)
client_input_size = sys.getsizeof(client_input)
if client_input_size > max_buffer_size:
print("The input size is greater than expected {}".format(client_input_size))
decoded_input = client_input.decode("utf8").rstrip()
result = process_input(decoded_input)
return result
def process_input(input_str):
print("Processing the input received from client")
return "Hello " + str(input_str).upper()
if __name__ == "__main__":
main()在執行上述指令碼時,在終端中執行 server_thread1.py,如下所示:
python server_thread1.py Socket created Socket now listening
我們將觀察伺服器視窗並瞭解流程。現在開啟多個客戶端終端,執行客戶端執行緒
python client_thread1.py Enter 'quit' to exit -> Zack ->
在另一個終端中,執行另一個客戶端程式並觀察伺服器終端視窗:
python client_thread1.py Enter 'quit' to exit -> Python -> quit
另一個終端,執行客戶端執行緒:
python client_thread1.py Enter 'quit' to exit -> world! -> Anothny ->
我們可以看到我們的伺服器視窗將顯示類似以下內容的輸出:
Socket created Socket now listening Connected with 127.0.0.1:50275 Processing the input received from client Processed result: Hello ZACK Connected with 127.0.0.1:50282 Processing the input received from client Processed result: Hello PYTHON Processing the input received from client Client is requesting to quit Connection 127.0.0.1:50282 closed Connected with 127.0.0.1:50285 Processing the input received from client Processed result: Hello WORLD! Processing the input received from client Processed result: Hello ANOTHNY
因此,執行緒提供了處理多個套接字連線和客戶端的最常用技術之一。
廣告
資料結構
網路
關係型資料庫管理系統
作業系統
Java
iOS
HTML
CSS
Android
Python
C 程式設計
C++
C#
MongoDB
MySQL
Javascript
PHP