Rust में समवर्तीता और मल्टीथ्रेडिंग: सुरक्षा और प्रदर्शन

शुरुआती लोगों के लिए ऑनलाइन Python प्रशिक्षक

Python आसानी से सीखें बिना सिद्धांत के बोझ के। स्वचालित जांच के साथ व्यावहारिक कार्य हल करें और ब्राउज़र में सीधे कोड लिखें।

पाठ्यक्रम शुरू करें
```html

Rust में समवर्तीता और मल्टीथ्रेडिंग: सुरक्षित और तेज़ कोड लिखना



आधुनिक प्रोग्राम शायद ही कभी सिंगल-थ्रेड मोड में काम करते हैं। अनुरोधों को संसाधित करना, फ़ाइलों के साथ काम करना, नेटवर्क ऑपरेशन - इन सबके लिए कार्यों के समानांतर निष्पादन की आवश्यकता होती है। Rust समवर्तीता के लिए एक अद्वितीय दृष्टिकोण प्रदान करता है: यह कंपाइलेशन चरण में मेमोरी सुरक्षा की गारंटी देता है, डेटा रेस को रोकता है। इस लेख में, हम Rust में threads, channels, mutexes और asynchrony के साथ काम करने का तरीका समझेंगे।



1. मल्टीथ्रेडिंग की मूल बातें: थ्रेड बनाना और प्रबंधित करना



Rust में, थ्रेड मानक लाइब्रेरी std::thread के माध्यम से बनाए जाते हैं। प्रत्येक थ्रेड स्वतंत्र रूप से निष्पादित होता है, लेकिन कंपाइलर वेरिएबल के जीवनकाल पर सख्ती से नज़र रखता है।



थ्रेड बनाना

use std::thread;use std::time::Duration;

fn main() { let handle = thread::spawn(|| { for i in 1..10 { println!("थ्रेड: {}", i); thread::sleep(Duration::from_millis(100)); } });

for i in 1..5 { println!("मुख्य थ्रेड: {}", i); thread::sleep(Duration::from_millis(100)); }

handle.join().unwrap(); // थ्रेड के समाप्त होने की प्रतीक्षा करें}


क्लोजर में स्वामित्व कैप्चर करना

यदि थ्रेड बाहरी स्कोप से वेरिएबल का उपयोग करता है, तो move के माध्यम से स्वामित्व स्थानांतरित करना होगा:

let data = vec![1, 2, 3];

let handle = thread::spawn(move || { println!("डेटा: {:?}", data);});

handle.join().unwrap();// println!("{:?}", data); // त्रुटि! data स्थानांतरित हो गया


2. डेटा साझा करना: म्यूटेक्स और लॉक



कई थ्रेड्स से साझा डेटा तक सुरक्षित पहुंच के लिए, Rust Arc (परमाणु संदर्भ काउंटर) के साथ Mutex (म्यूटेक्स) का उपयोग करता है।



Mutex और Arc के साथ उदाहरण

use std::sync::{Arc, Mutex};use std::thread;

fn main() { let counter = Arc::new(Mutex::new(0)); let mut handles = vec![];

for _ in 0..10 { let counter = Arc::clone(&counter); let handle = thread::spawn(move || { let mut num = counter.lock().unwrap(); *num += 1; }); handles.push(handle); }

for handle in handles { handle.join().unwrap(); }

println!("परिणाम: {}", *counter.lock().unwrap()); // 10}


महत्वपूर्ण: Mutex स्कोप से बाहर निकलने पर स्वचालित रूप से अनलॉक हो जाता है। यह कंपाइलेशन स्तर पर deadlock (पारस्परिक अवरोध) को रोकता है।



RwLock — बार-बार पढ़ने के लिए

यदि डेटा शायद ही कभी बदलता है लेकिन अक्सर पढ़ा जाता है, तो RwLock का उपयोग करें:

use std::sync::RwLock;

let lock = RwLock::new(5);

{ let r1 = lock.read().unwrap(); let r2 = lock.read().unwrap(); // एक साथ पढ़ सकते हैं println!("{} {}", r1, r2);}

{ let mut w = lock.write().unwrap(); *w += 1; // लिखना पढ़ने को ब्लॉक करता है}


3. चैनल: थ्रेड्स के बीच संदेश भेजना



Rust चैनलों (std::sync::mpsc) के माध्यम से एक्टर मॉडल का समर्थन करता है। यह थ्रेड्स को साझा मेमोरी के बिना डेटा का आदान-प्रदान करने की अनुमति देता है।



चैनल के साथ उदाहरण

use std::sync::mpsc;use std::thread;

fn main() { let (tx, rx) = mpsc::channel();

thread::spawn(move || { let vals = vec!["hello", "from", "the", "thread"]; for val in vals { tx.send(val).unwrap(); thread::sleep(std::time::Duration::from_secs(1)); } });

for received in rx { println!("प्राप्त: {}", received); }}


एकाधिक प्रेषक

mpsc::Sender की मदद से कई थ्रेड्स के लिए प्रेषक को क्लोन किया जा सकता है:

let (tx, rx) = mpsc::channel();let tx1 = tx.clone();

thread::spawn(move || { tx1.send("थ्रेड 1").unwrap(); });thread::spawn(move || { tx.send("```

ब्लॉग

पुस्तक अनुशंसाएँ