← Back to C++ Course | Chapter 17: Advanced C++ | Lesson 13 of 17

C++ में Mutex और Locks

एक mutex एक single-room bathroom की चाबी जैसा है: एक बार में सिर्फ एक thread इसे hold कर सकता है। यह threads को shared data गड़बड़ करने से रोकता है, और locks इसे manage करने में मदद करते हैं।
Syntax
cpp
#include <mutex>

std::mutex mutex_name;

mutex_name.lock();
// critical section
mutex_name.unlock();

std::lock_guard<std::mutex> guard(mutex_name);  // unlocks automatically

Data Races और Mutex

एक data race तब होती है जब कई threads एक ही समय पर same shared memory location में लिखने की कोशिश करते हैं, corrupted data की ओर ले जाते हुए। आप shared data को एक 'std::mutex' से protect कर सकते हैं यह सुनिश्चित करने के लिए कि एक बार में सिर्फ एक thread इसे access कर सके।

उदाहरण: Data Races and Mutex

cpp
#include <iostream>
#include <mutex>

std::mutex m;
int counter = 0;

void increment() {
	m.lock();
	counter++; // protected from concurrent writes
	m.unlock();
}

int main() {
	increment();
	std::cout << counter << std::endl;
	return 0;
}

Lock Guard (std::lock_guard)

Manual lock() और unlock() इस्तेमाल करना dangerous हो सकता है क्योंकि अगर आपका code एक exception throw करे या early return करे, mutex हमेशा के लिए locked रह जाता है। एक mutex lock करने के लिए 'std::lock_guard' इस्तेमाल करें। यह scope से बाहर जाने पर automatically mutex unlock करता है।

उदाहरण: Lock Guard (std::lock_guard)

cpp
#include <iostream>
#include <mutex>

std::mutex m;
int counter = 0;

void increment() {
	std::lock_guard<std::mutex> lock(m); // auto-unlocks, even on early return/exception
	counter++;
}

int main() {
	increment();
	std::cout << counter << std::endl;
	return 0;
}

Unique Lock (std::unique_lock)

'std::unique_lock' class lock_guard का एक ज़्यादा flexible version है। यह आपको किसी भी point पर manually mutex lock और unlock करने, deferred lock acquisitions, और time-delayed locks manage करने देती है।

उदाहरण: Unique Lock (std::unique_lock)

cpp
#include <iostream>
#include <mutex>

std::mutex m;

int main() {
	std::unique_lock<std::mutex> lock(m); // can unlock/relock manually
	lock.unlock();
	lock.lock();
	std::cout << "Manually managed lock" << std::endl;
	return 0;
}

Deadlocks

एक deadlock तब होता है जब दो threads हमेशा के लिए block हो जाते हैं, हर एक दूसरे से hold किए एक mutex का wait करते हुए। Deadlocks से बचने के लिए, कई mutexes को safely और simultaneously lock करने के लिए C++17 का 'std::scoped_lock' इस्तेमाल करें।

उदाहरण: Deadlocks

cpp
#include <iostream>
#include <mutex>

std::mutex m1, m2;

int main() {
	std::lock(m1, m2); // locks both without risking a deadlock, unlike locking separately
	std::lock_guard<std::mutex> lock1(m1, std::adopt_lock);
	std::lock_guard<std::mutex> lock2(m2, std::adopt_lock);
	std::cout << "Both locked safely" << std::endl;
	return 0;
}

Shared Memory के लिए Best Practices

अपने critical sections (आपके code के वे हिस्से जो locked हैं) जितना हो सके छोटा रखें। यह सुनिश्चित करता है कि threads locks के लिए कम time wait करने में खर्च करें, जो program throughput improve करता है।

उदाहरण: Best Practices for Shared Memory

cpp
#include <iostream>
#include <mutex>

std::mutex m;
int counter = 0;

void increment() {
	{
		std::lock_guard<std::mutex> lock(m); // critical section kept as small as possible
		counter++;
	}
	std::cout << "Non-critical work outside the lock" << std::endl;
}

int main() {
	increment();
	std::cout << counter << std::endl;
	return 0;
}
Related Topics
{# common_mistakes/chapter_summary/browser_support: on Hindi pages the view already swaps in the hi_ translation fields (or blanks these out if untranslated), so this renders correctly for both languages without a lang_code check here. #}
आम गलतियां
  1. manually locked एक mutex unlock करना भूल जाना।
  2. अलग-अलग threads में दो mutexes अलग-अलग order में lock करना, जो deadlock cause करता है।
  3. lock hold किए बिना shared data access करना, जो एक data race cause करता है।

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.