मल्टीथ्रेडिंग क्या है?
मल्टीथ्रेडिंग मल्टीटास्किंग का एक विशेष रूप है और मल्टीटास्किंग वह फीचर है जो आपके कंप्यूटर को दो या अधिक प्रोग्राम्स को समवर्ती रूप से चलाने की अनुमति देता है। सामान्यतः, मल्टीटास्किंग के दो प्रकार होते हैं: प्रोसेस-आधारित और थ्रेड-आधारित।
- प्रोसेस-आधारित मल्टीटास्किंग प्रोग्राम्स के समवर्ती निष्पादन को संभालता है।
- थ्रेड-आधारित मल्टीटास्किंग एक ही प्रोग्राम के टुकड़ों के समवर्ती निष्पादन से संबंधित है।
एक मल्टीथ्रेडेड प्रोग्राम में दो या अधिक भाग होते हैं जो समवर्ती रूप से चल सकते हैं। ऐसे प्रोग्राम के प्रत्येक भाग को थ्रेड कहा जाता है, और प्रत्येक थ्रेड निष्पादन का एक अलग पथ परिभाषित करता है।
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 का उपयोग थ्रेड को स्पष्ट रूप से बाहर निकलने के लिए किया जाता है। आमतौर पर, 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;
printf("Hello World! Thread ID, %d\n", tid);
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) {
printf("Error:unable to create thread, %d\n", rc);
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