Linux पर, आप POSIX थ्रेड (pthread) लाइब्रेरी का उपयोग करके C/C++ में थ्रेड बना और प्रबंधित कर सकते हैं। अन्य ऑपरेटिंग सिस्टमों के विपरीत, लिनक्स में एक थ्रेड और एक प्रक्रिया के बीच थोड़ा अंतर होता है। इसलिए लिनक्स अक्सर अपने थ्रेड्स को हल्के वजन की प्रक्रियाओं के रूप में संदर्भित करता है।
pthread लाइब्रेरी का उपयोग करके, आप थ्रेड्स बना सकते हैं, उनके समाप्त होने की प्रतीक्षा कर सकते हैं और उन्हें स्पष्ट रूप से समाप्त कर सकते हैं।
लिनक्स पर थ्रेड उपयोग का इतिहास
Linux संस्करण 2.6 से पहले, मुख्य थ्रेड कार्यान्वयन LinuxThreads था। प्रदर्शन और तुल्यकालन संचालन के मामले में इस कार्यान्वयन की महत्वपूर्ण सीमाएँ थीं। चल सकने वाले थ्रेड्स की अधिकतम संख्या पर एक सीमा उन्हें 1000 के दशक तक सीमित कर देती है।
2003 में, IBM और RedHat के डेवलपर्स के नेतृत्व में एक टीम इसे बनाने में सफल रही नेटिव पॉज़िक्स थ्रेड लाइब्रेरी (एनपीटीएल) परियोजना उपलब्ध है। लिनक्स पर जावा वर्चुअल मशीन के साथ प्रदर्शन के मुद्दों को हल करने के लिए इसे पहली बार RedHat Enterprise संस्करण 3 में पेश किया गया था। आज, जीएनयू सी पुस्तकालय में दोनों थ्रेडिंग तंत्रों के कार्यान्वयन शामिल हैं।
इनमें से कोई भी हरे धागे का कार्यान्वयन नहीं है, जिसे वर्चुअल मशीन पूरी तरह से उपयोगकर्ता मोड में प्रबंधित और चलाती है। जब आप pthread लाइब्रेरी का उपयोग करते हैं, तो हर बार प्रोग्राम शुरू होने पर कर्नेल एक थ्रेड बनाता है।
आप फ़ाइलों के अंतर्गत किसी भी चल रही प्रक्रिया के लिए थ्रेड-विशिष्ट जानकारी पा सकते हैं /proc/
थ्रेड्स का कार्य तर्क
थ्रेड वर्तमान में ऑपरेटिंग सिस्टम पर चलने वाली प्रक्रियाओं की तरह हैं। सिंगल-प्रोसेसर सिस्टम (जैसे माइक्रोकंट्रोलर) में, ऑपरेटिंग सिस्टम कर्नेल थ्रेड्स का अनुकरण करता है। यह लेन-देन को स्लाइसिंग के माध्यम से एक साथ चलाने की अनुमति देता है।
एक सिंगल-कोर ऑपरेटिंग सिस्टम वास्तव में एक समय में केवल एक ही प्रक्रिया को चला सकता है। हालाँकि, में मल्टी-कोर या मल्टी-प्रोसेसर सिस्टम, ये प्रक्रियाएँ एक साथ चल सकती हैं।
सी में थ्रेड निर्माण
आप उपयोग कर सकते हैं pthread_create एक नया थ्रेड बनाने के लिए कार्य करें। pthread.h शीर्ष लेख फ़ाइल में अन्य थ्रेड-संबंधित कार्यों के साथ-साथ इसकी हस्ताक्षर परिभाषा शामिल है। थ्रेड मुख्य प्रोग्राम के रूप में एक ही एड्रेस स्पेस और फ़ाइल डिस्क्रिप्टर का उपयोग करते हैं।
pthread लाइब्रेरी में सिंक्रोनाइज़ेशन ऑपरेशंस के लिए आवश्यक म्यूटेक्स और कंडीशनल ऑपरेशंस के लिए आवश्यक सपोर्ट भी शामिल है।
जब आप pthread लाइब्रेरी के फ़ंक्शंस का उपयोग कर रहे हों, तो आपको यह सुनिश्चित करना होगा कि कंपाइलर लिंक करता है pthread पुस्तकालय अपने निष्पादन योग्य में। यदि आवश्यक हो, तो आप कंपाइलर को लाइब्रेरी से लिंक करने का निर्देश दे सकते हैं -एल विकल्प:
जीसीसी -ओ परीक्षा test_thread.c -lpthread
Pthread_create फ़ंक्शन में निम्नलिखित हस्ताक्षर हैं:
int यहाँpthread_create(pthread_t *धागा, कॉन्स्टpthread_attr_t * अत्तर, खालीपन *(* start_routine)(खालीपन *), खालीपन * आर्ग)
यदि प्रक्रिया सफल होती है तो यह 0 लौटाता है। यदि कोई समस्या है, तो यह एक गैर-शून्य त्रुटि कोड लौटाता है। उपरोक्त फ़ंक्शन हस्ताक्षर में:
- धागा पैरामीटर प्रकार का है pthread_t. इस संदर्भ के साथ बनाया गया धागा हमेशा सुलभ रहेगा।
- attr पैरामीटर आपको कस्टम व्यवहार निर्दिष्ट करने देता है। आप शुरू होने वाले थ्रेड-विशिष्ट कार्यों की एक श्रृंखला का उपयोग कर सकते हैं pthread_attr_ इस मान को स्थापित करने के लिए। शेड्यूलिंग पॉलिसी, स्टैक साइज और डिटैचमेंट पॉलिसी संभावित अनुकूलन हैं।
- start_routine थ्रेड चलने वाले फ़ंक्शन को निर्दिष्ट करता है।
- आर्ग थ्रेड द्वारा फ़ंक्शन को पास की गई एक सामान्य डेटा संरचना का प्रतिनिधित्व करता है।
यहाँ एक उदाहरण आवेदन है:
#शामिल करना
#शामिल करना
#शामिल करना
#शामिल करनाखालीपन *कार्यकर्ता(खालीपन *आंकड़े)
{
चार *नाम = (चार*)आंकड़े;
के लिए (int यहाँ मैं = 0; मैं < 120; मैं++)
{
तुम सो जाओ(50000);
printf("थ्रेड नाम से हाय =% s\n", नाम);
}
printf("थ्रेड% s पूर्ण!\n", नाम);
वापस करनाव्यर्थ;
}
int यहाँमुख्य(खालीपन)
{
pthread_t th1, th2;
pthread_create(&th1, व्यर्थ, कार्यकर्ता, "एक्स");
pthread_create(&th2, व्यर्थ, कार्यकर्ता, "वाई");
नींद(5);
printf("मुख्य कार्यक्रम से बाहर निकल रहा है\n");
वापस करना0;
}
थ्रेड प्रकार
जब एक धागा से वापस आता है मुख्य() एक एप्लिकेशन में कार्य करता है, सभी थ्रेड्स समाप्त हो जाते हैं और सिस्टम प्रोग्राम द्वारा उपयोग किए जाने वाले सभी संसाधनों को मुक्त कर देता है। इसी तरह, किसी भी थ्रेड को कमांड के साथ बाहर निकलने पर a बाहर निकलना(), आपका प्रोग्राम सभी थ्रेड्स को समाप्त कर देगा।
साथ pthread_join फ़ंक्शन, आप इसके बजाय थ्रेड के समाप्त होने की प्रतीक्षा कर सकते हैं। इस फ़ंक्शन का उपयोग करने वाला थ्रेड तब तक ब्लॉक रहेगा जब तक अपेक्षित थ्रेड समाप्त नहीं हो जाता। सिस्टम से उपयोग किए जाने वाले संसाधन ऐसे मामलों में भी वापस नहीं आते हैं जैसे कि जुड़ने योग्य थ्रेड्स की समाप्ति, सीपीयू द्वारा अनिर्धारित, या यहां तक कि जुड़ने में विफल होना ptread_join.
कभी-कभी ऐसी स्थितियाँ होती हैं जहाँ pthread_join के साथ जुड़ने का कोई मतलब नहीं होता है; यदि भविष्यवाणी करना असंभव है कि धागा कब समाप्त होगा, उदाहरण के लिए। इस मामले में, आप यह सुनिश्चित कर सकते हैं कि सिस्टम उस बिंदु पर सभी संसाधनों को स्वचालित रूप से वापस कर देता है जहां धागा वापस आता है।
इसे प्राप्त करने के लिए, आपको संबंधित थ्रेड्स को इसके साथ शुरू करना चाहिए जुदा जुदा दर्जा। धागा शुरू करते समय, अलग करना स्थिति को थ्रेड विशेषता मानों के माध्यम से या इसके साथ सेट किया जा सकता है pthread_detach समारोह:
int यहाँpthread_attr_setdetachstate(&एटीआर, PTHREAD_CREATE_DETACHED);
int यहाँpthread_detach(pthread_t धागा);
यहाँ pthread_join() का एक उदाहरण उपयोग है। निम्नलिखित के साथ पहले कार्यक्रम में मुख्य कार्य को बदलें:
int यहाँमुख्य(खालीपन)
{
pthread_t th1, th2;
pthread_create(&th1, व्यर्थ, कार्यकर्ता, "एक्स");
pthread_create(&th2, व्यर्थ, कार्यकर्ता, "वाई");
नींद(5);
printf("मुख्य कार्यक्रम से बाहर निकल रहा है\n");
pthread_join (th1, व्यर्थ);
pthread_join (th2, व्यर्थ);
वापस करना0;
}
जब आप प्रोग्राम को संकलित और चलाते हैं, तो आपका आउटपुट होगा:
हाय थ्रेड वाई से
हाय थ्रेड एक्स से
हाय थ्रेड वाई से
...
हाय थ्रेड वाई से
मुख्य कार्यक्रम से बाहर निकलना
हाय थ्रेड एक्स से
...
हाय थ्रेड एक्स से
थ्रेड एक्स हो गया!
हाय थ्रेड वाई से
थ्रेड वाई हो गया!
धागा समाप्ति
आप किसी थ्रेड को pthread_cancel पर कॉल करके रद्द कर सकते हैं, संबंधित पास कर सकते हैं pthread_t पहचान:
int यहाँpthread_cancel(pthread_t धागा);
आप इसे निम्नलिखित कोड में कार्रवाई में देख सकते हैं। फिर से, केवल मुख्य कार्य अलग है:
int यहाँमुख्य(खालीपन)
{
pthread_t th1, th2;
pthread_create(&th1, व्यर्थ, कार्यकर्ता, "एक्स");
pthread_create(&th2, व्यर्थ, कार्यकर्ता, "वाई");
नींद(1);
printf("> थ्रेड वाई रद्द करना!!\n");
pthread_cancel (th2);
तुम सो जाओ(100000);
printf("> थ्रेड एक्स को रद्द किया जा रहा है!\n");
pthread_cancel (th1);
printf("मुख्य कार्यक्रम से बाहर निकल रहा है\n");
वापस करना0;
}
थ्रेड्स क्यों बनाए जाते हैं?
ऑपरेटिंग सिस्टम हमेशा एक या अधिक CPU पर थ्रेड चलाने का प्रयास करते हैं, या तो स्व-निर्मित सूची से या उपयोगकर्ता द्वारा बनाई गई थ्रेड सूची से। कुछ धागे नहीं चल सकते क्योंकि वे हार्डवेयर से इनपुट/आउटपुट सिग्नल की प्रतीक्षा कर रहे हैं। वे स्वेच्छा से प्रतीक्षा भी कर सकते हैं, किसी अन्य थ्रेड से प्रतिक्रिया की प्रतीक्षा कर रहे हैं, या किसी अन्य थ्रेड ने उन्हें ब्लॉक कर दिया है।
आप उन संसाधनों को समायोजित कर सकते हैं जिन्हें आप उन थ्रेड्स को आवंटित करते हैं जिन्हें आप pthread का उपयोग करके बनाते हैं। यह एक कस्टम शेड्यूलिंग नीति हो सकती है, या आप चाहें तो FIFO या राउंड-रॉबिन जैसे शेड्यूलिंग एल्गोरिदम चुन सकते हैं।