← Back to Go Course | Chapter 11: Concurrency | Lesson 6 of 8

sync.Mutex का उपयोग

एक mutex एक single bathroom key जैसी है -- एक समय में सिर्फ एक goroutine इसे पकड़ सकता है और shared resource उपयोग कर सकता है, और बाकी सबको अपनी बारी का इंतज़ार करना होता है।
Syntax
go
var mu sync.Mutex
mu.Lock()
defer mu.Unlock()
// critical section

Protecting Shared State

एक sync.Mutex यह सुनिश्चित करता है कि एक समय में सिर्फ एक goroutine Lock() और Unlock() के बीच का code execute कर सके, concurrent goroutines को एक साथ इसे modify करके shared data corrupt करने से रोकते हुए।

उदाहरण: Protecting Shared State

markup
// Every Go file belongs to a package; main builds an executable
package main

// Import the packages this program uses
import (
	"fmt"
	"sync"
)

// Define a struct type named Counter
type Counter struct {
	mu    sync.Mutex
	value int
}

// Define the method Increment on type Counter
func (c *Counter) Increment() {
	c.mu.Lock()
	// defer runs this call when the surrounding function returns
	defer c.mu.Unlock()
	c.value++
}

// main is where the program starts running
func main() {
	// Short declaration: create c and infer the type
	c := &Counter{}
	// Declare wg with the zero value of its type
	var wg sync.WaitGroup
	for i := 0; i < 100; i++ {
		wg.Add(1)
		go func() {
			defer wg.Done()
			c.Increment()
		}()
	}
	wg.Wait()
	fmt.Println(c.value)
}

Always Pair Lock with defer Unlock

Lock() के तुरंत बाद defer उपयोग करना गारंटी देता है कि function चाहे कैसे भी exit हो -- जल्दी returns या एक panic सहित -- Unlock() चलेगा, जो permanently हर दूसरे goroutine को lock out करने से बचाता है।

उदाहरण: Always Pair Lock with defer Unlock

markup
// Every Go file belongs to a package; main builds an executable
package main

// Import the packages this program uses
import (
	"fmt"
	"sync"
)

// Define a struct type named SafeMap
type SafeMap struct {
	mu   sync.Mutex
	data map[string]int
}

// Define the method Set on type SafeMap
func (m *SafeMap) Set(key string, value int) {
	m.mu.Lock()
	// defer runs this call when the surrounding function returns
	defer m.mu.Unlock()
	m.data[key] = value
}

// main is where the program starts running
func main() {
	// Short declaration: create m and infer the type
	m := &SafeMap{data: make(map[string]int)}
	m.Set("a", 1)
	// Print the values followed by a newline
	fmt.Println(m.data)
}

What Happens Without a Mutex

बिना किसी mutex (या दूसरे synchronization) के, एक ही variable को concurrently पढ़ने और लिखने वाले कई goroutines एक data race produce करते हैं -- एक अप्रत्याशित, कभी-कभी चुपचाप गलत result जो हर run में अलग हो सकता है।

Note: missing synchronization पकड़ने के लिए असली concurrent code पर race detector ('go run -race') चलाएं।

उदाहरण: What Happens Without a Mutex

markup
// Every Go file belongs to a package; main builds an executable
package main

// Import the packages this program uses
import (
	"fmt"
	"sync"
)

// main is where the program starts running
func main() {
	// Declare mu with the zero value of its type
	var mu sync.Mutex
	// Short declaration: create total and infer the type
	total := 0
	// Declare wg with the zero value of its type
	var wg sync.WaitGroup
	// Loop: repeat while the condition holds
	for i := 0; i < 50; i++ {
		wg.Add(1)
		// Start this call in a new goroutine (runs concurrently)
		go func() {
			defer wg.Done()
			mu.Lock()
			total++
			mu.Unlock()
		}()
	}
	wg.Wait()
	fmt.Println("total:", total)
}
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. Lock() के बाद Unlock() call करना भूल जाना, permanently उस mutex का इंतज़ार कर रहे हर दूसरे goroutine को block करते हुए।
  2. एक mutex lock करना, फिर बिना unlock किए किसी error path पर जल्दी return करना -- हमेशा Lock() को एक deferred Unlock() के साथ जोड़ें।
  3. sync.Mutex रखने वाले किसी struct को value से copy करना, जो lock को दोहराता है और mutual exclusion की गारंटी तोड़ देता है।
चैप्टर सारांश
  • sync.Mutex mutual exclusion प्रदान करता है: एक समय में सिर्फ एक goroutine lock रख सकता है।
  • Lock() mutex acquire करता है (अगर दूसरा goroutine इसे रखे हो तो block करते हुए), Unlock() इसे release करता है।
  • Lock() के ठीक बाद defer mu.Unlock() release की गारंटी देने का standard तरीका है, जल्दी returns पर भी।
  • एक mutex shared data को concurrent, unsynchronized access से बचाता है जो अन्यथा एक data race का कारण बनता।
🔒

Chapter Quiz — Complete all 8 topics to unlock

0/8 topics done

Complete these topics first:

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.