मल्टीथ्रेडिंग मल्टीटास्किंग का एक विशेष रूप है और मल्टीटास्किंग वह विशेषता है जो आपके कंप्यूटर को दो या अधिक प्रोग्राम्स को 동시에 चलाने की अनुमति देती है। सामान्यतः, मल्टीटास्किंग दो प्रकार की होती है: प्रोसेस-बेस्ड और थ्रेड-बेस्ड।
- प्रोसेस-बेस्ड मल्टीटास्किंग प्रोग्राम्स के समवर्ती निष्पादन को संभालती है।
- थ्रेड-बेस्ड मल्टीटास्किंग एक ही प्रोग्राम के टुकड़ों के समवर्ती निष्पादन से संबंधित है।
एक मल्टीथ्रेडेड प्रोग्राम में दो या अधिक भाग होते हैं जो समवर्ती रूप से चल सकते हैं। ऐसे प्रोग्राम का प्रत्येक भाग एक थ्रेड कहलाता है, और प्रत्येक थ्रेड निष्पादन का एक अलग पथ परिभाषित करता है।
C++ में मल्टीथ्रेडेड एप्लिकेशन्स के लिए कोई बिल्ट-इन सपोर्ट नहीं है। इसके बजाय, यह इस सुविधा को प्रदान करने के लिए पूरी तरह से ऑपरेटिंग सिस्टम पर निर्भर करता है।
यह ट्यूटोरियल मानता है कि आप Linux OS पर काम कर रहे हैं और हम POSIX का उपयोग करके मल्टी-थ्रेडेड C++ प्रोग्राम लिखने जा रहे हैं। POSIX Threads, या Pthreads उन API को प्रदान करते हैं जो कई यूनिक्स-जैसे 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 का उपयोग थ्रेड को स्पष्ट रूप से समाप्त करने के लिए किया जाता है। आमतौर पर, 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! थ्रेड 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() : थ्रेड बना रहा है, " << i << endl;
rc = pthread_create(&threads[i], NULL, PrintHello, (void*)i);
if (rc) {
cout << "त्रुटि: थ्रेड बनाने में असमर्थ, " << rc << endl;
exit(-1);
}
}
pthread_exit(NULL);
}
आउटपुट
$ g++ test.cpp -lpthread
$ ./a.out
main() : थ्रेड बना रहा है, 0
main() : थ्रेड बना रहा है, 1
main() : थ्रेड बना रहा है, 2
main() : थ्रेड बना रहा है, 3
main() : थ्रेड बना रहा है, 4
Hello World! थ्रेड ID, 0
Hello World! थ्रेड ID, 1
Hello World! थ्रेड ID, 2
Hello World! थ्रेड ID, 3
Hello World! थ्रेड ID, 4
आधुनिक C++ (C++11 और बाद) में std::thread
#include <iostream>
#include <thread>
#include <vector>
using namespace std;
void PrintHello(int id) {
cout << "Hello World! थ्रेड ID: " << id << endl;
}
int main() {
vector threads;
for (int i = 0; i < 5; i++) {
threads.emplace_back(PrintHello, i);
}
for (auto& t : threads) {
t.join(); // थ्रेड के खत्म होने का इंतजार करें
}
return 0;
}
महत्वपूर्ण अंतर
| पहलू | pthread (C-स्टाइल) | std::thread (C++11+) |
|---|---|---|
| हेडर | <pthread.h> | <thread> |
| कंपाइल फ्लैग | -lpthread | -pthread (GCC/Clang) |
| RAII सपोर्ट | नहीं | हां (ऑब्जेक्ट डिस्ट्रक्शन पर join/detach) |
| लैंब्डा सपोर्ट | मुश्किल | सीधा सपोर्ट |
| एक्सेप्शन हैंडलिंग | मैन्युअल | बेहतर सपोर्ट |