মাল্টিথ্রেডিং হলো মাল্টিটাস্কিংর একটি বিশেষ রূপ এবং মাল্টিটাস্কিং হলো वो ফিচার যা আপনার কম্পিউটারকে দুটি বা তার অধিক প্রোগ্রাম সমবর্তি রান করার অনুমতি দেয়। সাধারণত, মাল্টিটাস্কিং দুটি টাইপের: প্রসেস-বেসড এবং থ্রেড-বেসড।
প্রসেস-বেসড মাল্টিটাস্কিং প্রোগ্রামগুলোর সমবর্তি এক্সিকিউশন হ্যান্ডেল করে। থ্রেড-বেসড মাল্টিটাস্কিং একই প্রোগ্রামের টুকরোগুলো সমবর্তি এক্সিকিউশন হ্যান্ডেল করে।
একটি মাল্টিথ্রেডেড প্রোগ্রামে দুটি বা তার অধিক পার্ট থাকে যা সমবর্তি রান করতে পারে। এমন একটি প্রোগ্রামের প্রতিটি পার্টকে থ্রেড বলা হয়, এবং প্রতিটি থ্রেড এক্সিকিউশনের আলাদা পথ সংজ্ঞায়িত করে।
C++ মাল্টিথ্রেডেড অ্যাপ্লিকেশনের জন্য কোনো বিল্ট-ইন সাপোর্ট 갖고 না। বরং, এটি সম্পূর্ণরূপে অপারেটিং সিস্টেমের ওপর নির্ভর করে এই ফিচার প্রদানের জন্য।
এই টিউটোরিয়ালে ধরে নেওয়া হয়েছে আপনি Linux OS-এ কাজ করছেন এবং আমরা POSIX ব্যবহার করে মাল্টিথ্রেডেড C++ প্রোগ্রাম লিখব। POSIX Threads, বা Pthreads API প্রদান করে যা অনেক Unix-লাইক POSIX সিস্টেমে উপলব্ধ যেমন FreeBSD, NetBSD, GNU/Linux, Mac OS X এবং Solaris।
POSIX থ্রেড তৈরি করার নিচের রুটিনটি ব্যবহৃত হয় −
#include <pthread.h> pthread_create (thread, attr, start_routine, arg)
এখানে, pthread_create একটি নতুন থ্রেড তৈরি করে এবং সেটি এক্সিকিউটেবল করে। এই রুটিন আপনার কোডের যেকোনো জায়গা থেকে যেকোনো সংখ্যক বার কল করা যায়। প্যারামিটারগুলোর বর্ণনা নিচে দেওয়া হলো।
| প্যারামিটার | বর্ণনা |
|---|---|
| thread | সাবরুটিন দ্বারা রিটার্ন করা নতুন থ্রেডের জন্য একটি অপেক, ইউনিক আইডেন্টিফায়ার। |
| attr | একটি অপেক অ্যাট্রিবিউট অবজেক্ট যা থ্রেড অ্যাট্রিবিউট সেট করতে ব্যবহৃত হতে পারে। আপনি একটি থ্রেড অ্যাট্রিবিউট অবজেক্ট স্পেসিফাই করতে পারেন, অথবা ডিফল্ট ভ্যালু জন্য NULL। |
| start_routine | C++ রুটিন যা থ্রেড তৈরি হওয়ার পর এক্সিকিউট করবে। |
| arg | একটি সিঙ্গেল আর্গুমেন্ট যা start_routine-এ পাস করা যায়। এটি রেফারেন্স বাই পাস করা হয় void টাইপ কাস্ট করে। NULL ব্যবহার করা যায় যদি কোনো আর্গুমেন্ট পাস না করা হয়। |
একটি প্রসেস দ্বারা তৈরি করা যেতে পারে সর্বোচ্চ থ্রেডের সংখ্যা ইমপ্লিমেন্টেশন-ডিপেনডেন্ট। একবার তৈরি হলে, থ্রেডগুলো পিয়ার, এবং অন্য থ্রেড তৈরি করতে পারে। থ্রেডগুলোর মধ্যে কোনো ইমপ্লাইড হায়ারার্কি বা ডিপেনডেন্সি নেই।
থ্রেড টার্মিনেট করা
POSIX থ্রেড টার্মিনেট করতে নিচের রুটিনটি ব্যবহৃত হয় −
#include <pthread.h> pthread_exit (status)
এখানে pthread_exit eksplisitley একটি থ্রেড থেকে বের হতে ব্যবহৃত হয়। সাধারণত, pthread_exit() রুটিনটি কল করা হয় যখন একটি থ্রেড তার কাজ সম্পন্ন করে এবং আর এক্সিস্ট করার প্রয়োজন নেই।
যদি main() তৈরি করা থ্রেডগুলো থেকে আগে ফিনিশ করে, এবং pthread_exit()-এ এক্সিট করে, তবে অন্যান্য থ্রেডগুলো এক্সিকিউট হতে থাকবে। অন্যথায়, main() ফিনিশ করলে সেগুলো স্বয়ংক্রিয়ভাবে টার্মিনেট হয়ে যাবে।
উদাহরণ
#include <iostream> #include <cstdlib> #include <pthread.h> using namespace std; #define NUM_THREADS 5 void *PrintHello(void *threadid) { long tid; tid = (long)threadid; cout << "Hello World! Thread ID, " << tid << endl; pthread_exit(NULL); } int main () { pthread_t threads[NUM_THREADS]; int rc; int i; for( i = 0; i < NUM_THREADS; i++ ) { cout << "main() : creating thread, " << i << endl; rc = pthread_create(&threads[i], NULL, PrintHello, (void *)i); if (rc) { cout << "Error:unable to create thread," << rc << endl; exit(-1); } } pthread_exit(NULL); }আউটপুট
$gcc test.cpp -lpthread $./a.out main() : creating thread, 0 main() : creating thread, 1 main() : creating thread, 2 main() : creating thread, 3 main() : creating thread, 4 Hello World! Thread ID, 0 Hello World! Thread ID, 1 Hello World! Thread ID, 2 Hello World! Thread ID, 3 Hello World! Thread ID, 4