মাল্টি-থ্রেডিং কনসেপ্ট
মাল্টি-থ্রেডিং আধুনিক প্রোগ্রামিং ল্যাঙ্গুয়েজের প্রায় সব কোর কনসেপ্ট, বিশেষ করে পাইথনে এর সহজ বাস্তবায়নের কারণে।
একটি থ্রেড হলো একটি প্রোগ্রামের সাব-প্রোগ্রাম যা কোডের অন্যান্য অংশ থেকে স্বাধীনভাবে এক্সিকিউট হতে পারে। একটি থ্রেড একই কনটেক্সটে এক্সিকিউট হয় প্রোগ্রামের রাননেবল রিসোর্স (যেমন: মেমরি) শেয়ার করে।
যখন একটি সিঙ্গেল প্রসেসে, আমরা একসাথে একাধিক থ্রেড এক্সিকিউট করি, তাকে মাল্টি-থ্রেডিং বলা হয়।
থ্রেড বাস্তবায়নের জন্য পাইথন মাল্টি-থ্রেডিং মডিউল
প্রোগ্রামে থ্রেড বাস্তবায়ন করার জন্য পাইথন দুটি মডিউল প্রদান করে:
thread(পাইথন ২.x জন্য) বা_thread(পাইথন ৩.x জন্য) মডিউলthreadingমডিউল
thread মডিউল একটি ফাংশন হিসেবে থ্রেড তৈরি করে, অন্যদিকে threading মডিউল অবজেক্ট-ওরিয়েন্টেড পদ্ধতিতে থ্রেড তৈরি করার সুবিধা দেয়।
সিনট্যাক্স
_thread.start_new_thread(func, args[, kwargs])
উপরের কোডটি একটি নতুন থ্রেড শুরু করে এবং এর আইডেন্টিফায়ার রিটার্ন করে। প্রথম আর্গুমেন্ট হলো একটি ফাংশন func যা থ্রেডটি এক্সিকিউট করবে দ্বিতীয় আর্গুমেন্টের সাথে যা একটি টাপল যা পজিশনাল আর্গুমেন্টের তালিকা ধারণ করে। অপশনাল kwargs আর্গুমেন্টটি কীওয়ার্ড আর্গুমেন্টের একটি ডিকশনারি নির্দিষ্ট করে। ফাংশন রিটার্ন করলে থ্রেড সাইলেন্টলি এক্সিট করে।
এখানে আমরা একটি বেসিক ক্লায়েন্ট-সার্ভার অ্যাপ্লিকেশন দেখব। যেখানে ক্লায়েন্টরা মূলত একটি সকেট কানেকশন খুলে সার্ভারের কাছে কুয়েরি পাঠায়। সার্ভার প্রতিক্রিয়া জানায়।
আর্গুমেন্ট ছাড়া চালালে, এই প্রোগ্রামটি একটি TCP সকেট সার্ভার হিসেবে শুরু হয় যা 127.0.0.1 এর পোর্ট ৮০০০-এ কানেকশন লিসেন করে।
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 # নাল অপারেশন
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 # আربیট্রারি নন-প্রিভিলেজড পোর্ট
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) # ৬ রিকোয়েস্ট কিউ করুন
print("Socket now listening")
# ইনফিনিট লুপ - প্রতিটি রিকোয়েস্টের জন্য রিসেট না করে
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
সুতরাং, থ্রেড একাধিক সকেট কানেকশন এবং ক্লায়েন্ট হ্যান্ডেল করার সবচেয়ে সাধারণ টেকনিকlerden একটি।