Multithreading in C#: C# हमें कई तरह के Programming Features Provide करता है, जिनमें से एक Multi-Threaded Programming है, जिसे C# Predefined Libraries के माध्यम से Support करता है। Multi-Threaded Programming में एक ही समय पर एक ही Program के दो या दो से ज्यादा Parts समानान्तर रूप से Run होते हैं। लेकिन Multi-Threaded Programming को अच्छी तरह से समझने से पहले हमें कुछ Basic बातों के बारे में जानना जरूरी है, जो कि अग्रानुसार हैं।
Windows Process
Process का Concept Windows Operating System में .NET Platform के Release होने से पहले से ही Exist है। सरल शब्दों में कहें तो किसी Running Program को Process कहा जाता है। Process एक Operating System Level Concept है, जिसका प्रयोग विभिन्न प्रकार के Resources के समूह जैसे कि External Code Libraries व Primary Thread को Describe करने तथा Running Program द्वारा Use किए जाने वाले जरूरी Memory Allocation के लिए किया जाता है। जहां Memory में Load होने वाले हर *.exe के Lifetime के दौरान Operating System एक अलग व Isolated Process Create करता है।
Application के Isolation के लिए Operating System द्वारा इस तरह से Isolated Approach को Use करके एक ज्यादा Robust व Stable Runtime Environment Create किया जाता है, जिसकी वजह से किसी एक Process के Failure के कारण किसी दूसरे Process पर इस Failure का प्रभाव नहीं पडता।
इसी तरह से एक Process का Data किसी भी तरह से किसी दूसरे Process द्वारा Directly Access नहीं किया जा सकताए जब तक कि हम स्वयं Windows Communication Foundation जैसे किसी Distributed Computing API का प्रयोग करके किसी Process को किसी दूसरे Process के Data को Access करने की Permission नहीं देते। इस तरह के Architecture के कारण .NET Platform हर Running Application Process को एक Fixed व Safe Boundary Provide करता है।
Windows Operating System हर Running Process को एक Unique Process Identifier (PID) Provide करता है, जिसकी वजह से Windows Operating System हर Process को Programmatically Control करते हुए Independent तरीके से Load या Unload सकता है अथवा हम स्वयं अपनी इच्छानुसार Windows Operating System के Task Manager (Ctrl+Shift+Esc) के माध्यम से किसी Process को Independent तरीके से Manually Load या Unload कर सकते हैं।
Threads
हर Window Process का एक Initial Thread होता है जो किसी Application के Entry Point की तरह काम करता है। Thread किसी Process के अन्दर Application के Execution का Path होता है। यानी किसी भी Application को Run करने के लिए Operating System द्वारा Process का जो First Thread Create किया जाता है, वह First Thread ही उस Application Process का Entry Point होता है जो कि Primary Thread कहलाता है।
हर .NET Executable Program जैसे कि Console Application, Windows Forms Application, WPF Application आदि अपने Entry Point को Main() Method द्वारा Mark करते हैं। जब ये Method Invoke होता है, तो Windows Operating System Automatically उस Application के लिए Primary Thread Create कर देता है।
जिन Processes में Execution का केवल एक ही Single Primary Thread होता है, वे मूल रूप से Thread Safe होते हैं क्योंकि इस प्रकार के .NET Applications में केवल एक ही Thread होता है, जो Application के Data को Access कर सकता है। लेकिन Single Threaded Processes की एक परेशानी ये होती है कि इस प्रकार के Applications में जब तक एक Task पूरा नहीं हो जाताए तब तक वह Application अगले Task को Execute नहीं करता।
उदाहरण के लिए किसी GUI Application में एक ही Form Window पर विभिन्न Controls दिखाई देते हैं। ऐसे में यदि हम किसी बहुत बडी File को Print करने के लिए Print Button पर Click करें और हमारा Application Single Threaded हो, तो जब तक वह File पूरी तरह से Print नहीं हो जाती, तब तक हम Form के किसी भी अन्य Control को उपयोग में नहीं ले सकते अथवा तब तक Form का कोई भी Control कोई Action Perform नहीं कर सकता व Response नहीं देता।
Single Threaded Applications की इस समस्या के कारण ही Windows API व .NET Platform किसी .NET Application के Primary Thread को Internally एक से ज्यादा Threads Create करने की सुविधा Provide करता है, जिन्हें Secondary Threads या Worker Threads के नाम से जाना जाता है।
Windows Application में हर Primary या Secondary Thread, Current Application Process में Execution का एक Unique Path बन जाता है। यानी Current Application के सभी Threads समानान्तर रूप से Run होते हैं और Current Process के सभी Data को समानान्तर रूप से Execute हो रहे सभी Threads के बीच Share होते हैं।
परिणामस्वरूप हम .NET के Multi-Threading Feature का प्रयोग करके Additional Threads Create कर सकते हैं और अपने Program की Responsiveness को Improve कर सकते हैं। Multi-Threaded Processes इस बात का भ्रम पैदा करते हैं कि एक ही समय पर समानान्तर रूप से एक से ज्यादा Tasks Perform हो रहे हैं। जबकि सच्चाई ये है कि CPU एक समय में केवल एक ही Task पूरा करता है लेकिन विभिन्न Threads में Run हो रहे विभिन्न Tasks को इतना तेजी से Switch करता है कि हमें लगता है कि सभी Tasks समानान्तर रूप से Run हो रहे हैं।
हालांकि हमें महसूस हो सकता है कि यदि हमारे Application के बहुत सारे Threads हों, तो हर Thread अलग-अलग कामों को Perform करेगा जिसकी वजह से हमारे Application की Performance Improve होगी। लेकिन वास्तव में ऐसा नहीं होता। क्योंकि यदि किसी Application में बहुत सारे Secondary Threads हों, तो Operating System को विभिन्न Threads पर बार-बार Switching करना पडेगा और Threads Switching में हमेंशा Extra समय लगता है, जिससे Application की Performance Improve नहीं बल्कि Degrade होगी।
जिन Machines (Computers, Mobiles, Smart Phones, Tablets, etc…) का CPU Non-Hyper-Threaded होता है, जिनमें Multi-Threading Ability नहीं होती यानी जो CPU समान समय पर एक से ज्यादा Threads के Codes को समानान्तर रूप से Execute करने में सक्षम नहीं होते। उन CPU Based Machines पर Operating System ही Multi-Threading का भ्रम पैदा करता है।
इस प्रकार के Single CPU Machine के लिए Operating System ही हमेंशा से Multi-Threading की सुविधा Provide करने के लिए Thread Priority के आधार पर Time-Slicing Technique का प्रयोग करके, एक समय में एक Thread को Execute करता रहा है।
परिणामस्वरूप जब एक Thread को Allot किया गया समय समाप्त हो जाता है, तब दूसरा Thread Execute होने लगता है और पहला वाला Thread CPU पर अपने Execution के समय को फिर से प्राप्त करने के लिए Wait करता रहता है।
हर Thread जब Running से Waiting State में जाता है, तो Currently वह जिस Task को Perform कर रहा होता है, उसे Thread Local Storage (TLS) नाम की Storage में Store कर देता है। ताकि जब फिर से उस Thread को Execute होने के लिए CPU का समय मिले, तब वह अपने Execution को फिर से उसी पिछली स्थिति से Restart करने के लिए अपने Data को TLS से प्राप्त कर सके, जहां से वह Running से Waiting State में गया था।
इस तरह से Single CPU Machines में हर Process का अपना स्वयं का Call-Stack होता है, जो इस बात का ध्यान रखता है कि Thread को Waiting से Running State में जाने के लिए किस Code को Execute करते हुए शुरूआत करनी है। Multiple Threads की इस प्रक्रिया को हम निम्न चित्र द्वारा Represent कर सकते हैं:
Interacting with Processes via .NET Platform
इससे पहले कि हम Multi-Threaded Assemblies Create करें, हमें ये समझना होगा कि हम .NET द्वारा Provided .NET Base Class Libraries का प्रयोग करते हुए किस तरह से Windows Operating System के Processes के साथ Interaction कर सकते हैं।
.NET Framework में हमें System.Diagnostics नाम का एक Namespace प्राप्त होता है, जिसमें बहुत सारे Types को Predefined किया गया है, जिनका प्रयोग करके हम किसी Process के साथ Programmatically Interact कर सकते हैं और विभिन्न प्रकार के Diagnostic Related जरूरतों को पूरा कर सकते हैं।
Process Type
ये Class हमें Local व Remote Processes को Access करने व किसी Process को Programmatically Start या Stop करने की सुविधा Provide करता है।
ProcessModule Type
ये Type किसी *.dll या *.exe Module को Represent करता है, जो कि किसी Particular Process में Load होता है। ProcessModule Type किसी भी प्रकार के Module को Represent कर सकता है, जिसमें COM-Based, .NET-Based व Traditional C-Based Binaries सम्मिलित हैं।
ProcessModuleCollection Type
ये Type हमें ProcessModule Objects का Strongly Typed Collection Provide करता है।
ProcessStartInfo Type
ये Type विभिन्न प्रकार की Values का एक Set Specify करता है, जिसे हम तब उपयोग में ले सकते हैं, जब हम Process.Start() Method का प्रयोग करके किसी Process को Start करते हैं।
ProcessThread Type
ये Type किसी Specified Process के किसी Thread को Represent करता है। इस Type का प्रयोग नया Secondary Thread Create करने के लिए नहीं किया जा सकताए बल्कि इसे केवल किसी Process के Threads की जानकारी प्राप्त करने यानी Diagnose करने के लिए ही Use किया जा सकता है।
ProcessThreadCollection Type
ये Type हमें ProcessThread Objects का Strongly Typed Collection Provide करता है।
System.Diagnostics.Process Class हमें किसी Local या Remote Machine पर Running Processes को Analyze करने की सुविधा देता है। ये Class हमें ऐसे Members Provide करता है जिनका प्रयोग करके हम Programmatically किसी Process को Start या Terminate कर सकते हैं, View या Modify कर सकते हैं, Process की Priority Set कर सकते हैं और किसी Process के Active Threads तथा@अथवा Modules की List प्राप्त कर सकते हैं। इस Class की कुछ मुख्य Properties निम्नानुसार हैं:
ExitTime Property
इस Property में किसी Terminate किए गए Process का DateTime Type में Ending TimeStamp Stored होता है।
Handle Property
ये Property हमें IntPtr के रूप में किसी Process को Operating System द्वारा Provided Handle Return करता है। ये Property उस समय काफी महत्वपूर्ण होती है, जब हम किसी Unmanaged Code के साथ Communication करते हैं।
Id Property
इस Property में किसी Process के साथ Associated PID होता है।
MachineName Property
इस Property में उस Machine का नाम होता है, जिस पर Associated Process Run हो रहा होता है।
MainWindowTitle Property
ये Property Running Process के Main Window का Title Return करता है। जबकि यदि Process का कोई Main Window न हो, तो ये Property एक Empty String Return करता है।
Modules Property
ये Property हमें Strongly Typed ProcessModuleCollection Type को Access करने की सुविधा देता है, जो कि Current Process में Loaded *.dll या *.exe Modules के Set को Represent करता है।
ProcessName Property
ये Property हमें हमारे Process का नाम Return करता है, जो कि सामान्यत: वही नाम होता है, जो हमारे Application या Program का नाम होता है।
StartTime Property
इस Property में किसी Start किए गए Process का DateTime Type में Starting TimeStamp Stored होता है।
Threads Property
ये Property किसी Thread के साथ Associated सभी Running Threads के समूह को ProcessThread Objects के Collection के रूप में Return करता है।
इन महत्वपूर्ण Properties के अलावा System.Diagnostics.Process Class में कुछ Methods को भी Define किया गया है, जो कि Process Diagnosis करते समय हमारे लिए काफी उपयोगी होते हैं। ये Methods निम्नानुसार हैं:
CloseMainWindow() Method
ये Method, Application के Main Window को एक Close Message Send करके उसके Process को Close कर देता है।
GetCurrentProcess() Method
ये एक Static Method है, जो एक नया Process Object Return करता है, जो कि Currently Active Process को Represent करता है।
GetProcesses() Method
ये एक Static Method है, जो किसी Specified Machine पर Run हो रहे विभिन्न Processes को Objects के एक Array की तरह Return करता है।
Kill() Method
ये Method Specified Process को Immediately Stop कर देता है।
Start() Method
ये Method Specified Process को Start कर देता है।
ये Article इस वेबसाईट पर Selling हेतु उपलब्ध EBook C#.NET in Hindi से लिया गया है। इसलिए यदि ये Article आपके लिए उपयोगी रहा, तो निश्चित रूप से ये पुस्तक भी आपके लिए काफी उपयोगी साबित होगी।
C#.NET in Hindi | Page:908 | Format: PDF