गो का समवर्ती मॉडल – गोरआउट्स और चैनल – किसी भी मुख्यधारा की भाषा में सबसे सरल और सबसे शक्तिशाली समवर्ती प्रणाली है। 2026 में, रेंज-ओवर-फ़ंक्शन इटरेटर और स्लॉग संरचित लॉगिंग के साथ गो 1.23 समवर्ती गो कोड को पहले से कहीं अधिक क्लीनर बनाता है। यह मार्गदर्शिका बुनियादी गोरोइन से लेकर उत्पादन पैटर्न तक सब कुछ कवर करती है।
📋 Table of Contents
गोरौटाइन्स – हल्के धागे
package main
import (
"fmt"
"sync"
"time"
)
func main() {
// goroutine = lightweight thread (starts with 2KB stack, not 1MB like OS threads)
go sayHello("World") // fire and forget
// Wait for goroutine using WaitGroup
var wg sync.WaitGroup
for i := 0; i < 5; i++ {
wg.Add(1)
go func(id int) {
defer wg.Done()
fmt.Printf("Worker %d done
", id)
time.Sleep(time.Duration(id) * time.Millisecond)
}(i)
}
wg.Wait() // block until all goroutines finish
fmt.Println("All workers done")
}
func sayHello(name string) {
time.Sleep(10 * time.Millisecond)
fmt.Printf("Hello, %s!
", name)
}
चैनल – गोरोइन्स के बीच संचार
package main
import "fmt"
func main() {
// Unbuffered channel — sender blocks until receiver ready
ch := make(chan int)
go func() {
ch <- 42 // send
}()
value := <-ch // receive
fmt.Println(value) // 42
// Buffered channel — sender blocks only when buffer full
buffered := make(chan string, 5)
buffered <- "hello"
buffered <- "world"
// Doesn't block because buffer has space
close(buffered)
// Range over closed channel
for msg := range buffered {
fmt.Println(msg)
}
// Directional channels in function signatures
produce := func(ch chan<- int) { // send-only
for i := 0; i < 5; i++ {
ch <- i
}
close(ch)
}
consume := func(ch <-chan int) { // receive-only
for n := range ch {
fmt.Println("received:", n)
}
}
dataCh := make(chan int, 10)
go produce(dataCh)
consume(dataCh)
}
चयन करें – मल्टीप्लेक्सिंग चैनल
package main
import (
"context"
"fmt"
"time"
)
func main() {
ch1 := make(chan string)
ch2 := make(chan string)
go func() {
time.Sleep(100 * time.Millisecond)
ch1 <- "from ch1"
}()
go func() {
time.Sleep(200 * time.Millisecond)
ch2 <- "from ch2"
}()
// Select picks whichever channel is ready first
for i := 0; i < 2; i++ {
select {
case msg1 := <-ch1:
fmt.Println(msg1)
case msg2 := <-ch2:
fmt.Println(msg2)
}
}
// With timeout
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
select {
case result := <-fetchData():
fmt.Println(result)
case <-ctx.Done():
fmt.Println("timeout:", ctx.Err())
}
// Non-blocking send with default
ch := make(chan int, 1)
select {
case ch <- 42:
fmt.Println("sent")
default:
fmt.Println("channel full, skipped")
}
}
वर्कर पूल पैटर्न
package main
import (
"fmt"
"sync"
)
type Job struct {
ID int
Data string
}
type Result struct {
JobID int
Output string
Err error
}
func workerPool(numWorkers int, jobs <-chan Job, results chan<- Result) {
var wg sync.WaitGroup
for i := 0; i < numWorkers; i++ {
wg.Add(1)
go func(workerID int) {
defer wg.Done()
for job := range jobs {
output, err := processJob(job)
results <- Result{JobID: job.ID, Output: output, Err: err}
}
}(i)
}
// Close results channel when all workers done
go func() {
wg.Wait()
close(results)
}()
}
func processJob(job Job) (string, error) {
return fmt.Sprintf("processed: %s", job.Data), nil
}
func main() {
jobs := make(chan Job, 100)
results := make(chan Result, 100)
// Start 5 workers
go workerPool(5, jobs, results)
// Send 20 jobs
go func() {
for i := 0; i < 20; i++ {
jobs <- Job{ID: i, Data: fmt.Sprintf("item-%d", i)}
}
close(jobs)
}()
// Collect results
for result := range results {
if result.Err != nil {
fmt.Printf("Job %d failed: %v
", result.JobID, result.Err)
continue
}
fmt.Printf("Job %d: %s
", result.JobID, result.Output)
}
}
संदर्भ – रद्दीकरण और समय सीमा
package main
import (
"context"
"fmt"
"time"
)
func fetchWithContext(ctx context.Context, url string) (string, error) {
// Check if context already cancelled
select {
case <-ctx.Done():
return "", ctx.Err()
default:
}
// Simulate slow operation
done := make(chan string, 1)
go func() {
time.Sleep(500 * time.Millisecond)
done <- "data from " + url
}()
select {
case data := <-done:
return data, nil
case <-ctx.Done():
return "", ctx.Err()
}
}
func main() {
// Context with deadline
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
defer cancel()
data, err := fetchWithContext(ctx, "https://api.example.com/data")
if err != nil {
fmt.Println("Error:", err)
return
}
fmt.Println(data)
// Pass context to database queries (Go standard pattern)
// db.QueryContext(ctx, "SELECT ...")
// http.NewRequestWithContext(ctx, "GET", url, nil)
}
सिंक पैकेज – म्यूटेक्स और वन्स
package main
import (
"fmt"
"sync"
"sync/atomic"
)
// Mutex for shared state
type SafeCounter struct {
mu sync.RWMutex
count map[string]int
}
func (c *SafeCounter) Increment(key string) {
c.mu.Lock()
defer c.mu.Unlock()
c.count[key]++
}
func (c *SafeCounter) Get(key string) int {
c.mu.RLock() // multiple readers allowed simultaneously
defer c.mu.RUnlock()
return c.count[key]
}
// sync.Once — run initialization exactly once
var (
dbOnce sync.Once
dbInstance *Database
)
func GetDB() *Database {
dbOnce.Do(func() {
dbInstance = &Database{} // initialized exactly once, even concurrent calls
})
return dbInstance
}
// Atomic operations — lockless for simple counters
var requestCount int64
func handleRequest() {
atomic.AddInt64(&requestCount, 1)
// Process request...
}
func getRequestCount() int64 {
return atomic.LoadInt64(&requestCount)
}
इरग्रुप – समवर्ती त्रुटियाँ
package main
import (
"context"
"fmt"
"golang.org/x/sync/errgroup"
)
func main() {
ctx := context.Background()
// Run goroutines, collect first error
g, ctx := errgroup.WithContext(ctx)
var user, posts, stats interface{}
g.Go(func() error {
var err error
user, err = fetchUser(ctx, 1)
return err
})
g.Go(func() error {
var err error
posts, err = fetchPosts(ctx, 1)
return err
})
g.Go(func() error {
var err error
stats, err = fetchStats(ctx, 1)
return err
})
// Wait for all goroutines
if err := g.Wait(); err != nil {
fmt.Println("Error:", err)
return
}
fmt.Println(user, posts, stats)
}
जब आप मंत्र का पालन करते हैं तो 2026 में गो समवर्ती सुरुचिपूर्ण और शक्तिशाली होता है: “संचार करके स्मृति साझा करें, स्मृति साझा करके संचार न करें।” गोरआउट्स का स्वतंत्र रूप से उपयोग करें (प्रत्येक की लागत ~ 2KB है), चैनलों और वेटग्रुप्स के साथ समन्वय करें, सभी लंबे समय से चल रहे संचालन में संदर्भ रद्दीकरण को संभालें, और साझा परिवर्तनीय स्थिति (चैनलों या परमाणु संचालन को प्राथमिकता दें) से बचें।
🔗 Share this article
✍️ Leave a Comment