Python
 Computer >> コンピューター >  >> プログラミング >> Python

Pythonでマルチスレッドを使用したソケットプログラミング?


マルチスレッドの概念

マルチスレッドは、スレッドの実装が単純であるため、ほとんどすべての最新のプログラミング言語、特にPythonのコアコンセプトです。

スレッドは、コードの他のセクションとは独立して実行できるプログラム内のサブプログラムです。スレッドは、メモリなどの同じコンテキスト共有プログラムの実行可能なリソースで実行されます。

単一のプロセスで複数のスレッドを同時に実行している場合、それはマルチスレッドと呼ばれます。

スレッド実装用のPythonマルチスレッドモジュール

プログラムにスレッドを実装するために、Pythonは2つのモジュールを提供します-

  • thread(python 2.xの場合)または_thread(python 3.xの場合)モジュール
  • スレッドモジュール

スレッドモジュールが関数としてスレッドを作成するのに対し、スレッドモジュールはスレッドを作成するためのオブジェクト指向のアプローチを提供します。

構文

_thread.start_new_thread(func, args[, kwargs])

上記は新しいスレッドを開始し、その識別子を返します。最初の引数は関数funcであり、スレッドは、引数の位置リストを持つタプルを含む2番目の引数で実行されます。オプションのkwargs引数は、キーワード引数の辞書を指定します。関数が戻ると、スレッドはサイレントに存在します。

ここでは、クライアントサーバーアプリケーションの基本的な例を示します。クライアントが基本的にソケット接続を開き、サーバーにクエリを送信する場合。サーバーが応答します。

引数なしで実行すると、このプログラムは、ポート8000​​で127.0.0.1への接続をリッスンするTCPソケットサーバーで起動します。

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

したがって、スレッドは、複数のソケット接続とクライアントを処理するための最も一般的な手法の1つを提供します。


  1. Pythonのメタクラスを使用したメタプログラミング

    メタプログラミングという用語は、コンピュータープログラムがそれ自体を操作したり、知識を持ったりしようとするコンピュータープログラミングを指します。 Pythonは、メタクラスと呼ばれる新しいタイプのクラスを介したクラスのメタプログラミングをサポートしています。 Pythonのメタクラスを介したメタプログラミングは、既存のコードを変更、ラップ、または生成することによってコードを操作する関数とクラスを構築することです。 メタプログラミングの主な機能は次のとおりです- メタクラス デコレータ クラスデコレータ メタクラスとは メタクラスの非常に限定された定義は、クラスを作成するクラスである

  2. Pythonでのタートルプログラミング

    カメはPythonの特別な羽です。 Turtleを使用すると、簡単に製図板に描くことができます。 まず、タートルモジュールをインポートします。次にウィンドウを作成し、次にタートルオブジェクトを作成し、タートルメソッドを使用して製図板に描画できます。 いくつかのカメの方法 方法 パラメータ 説明 Turtle() なし 新しいタートルオブジェクトを作成して返します forward() 金額 指定された量だけカメを前進させます backward() 金額 指定された量だけカメを後方に動かします right() 角度 カメを時計回りに回転させます left() 角