برنامه‌نویسی Concurrent با Go

ایجاد شده توسط دکتر مصطفی جلیلی در آموزش برنامه نویسی گولنگ 15 آوریل 2025
اشتراک گذاری


برنامه‌نویسی Concurrent با Go


در دنیای برنامه‌نویسی امروزی، نیاز به هم‌زمانی و انجام چندین کار به‌طور همزمان در برنامه‌ها بیش از پیش حس می‌شه. زبان Go ابزارهای قدرتمندی مثل Goroutines و Channels رو برای انجام عملیات هم‌زمان (concurrent) در اختیار شما قرار می‌ده. در این بخش از آموزش، با این مفاهیم آشنا می‌شویم و یاد می‌گیریم چطور با استفاده از این ابزارها برنامه‌های هم‌زمان در Go بسازیم.




Goroutine چیست؟


Goroutine به‌طور ساده یک وظیفه هم‌زمان در Go است. این وظایف به شما این امکان رو می‌دهند که کدهای مختلف رو به‌طور هم‌زمان اجرا کنید. در واقع، Go به شما این اجازه رو می‌ده که تعداد زیادی از این Goroutine‌ها رو در یک برنامه راه‌اندازی کنید و کارهای مختلف رو بدون وقفه انجام بدید.


راه‌اندازی یک Goroutine:


go func() {
fmt.Println("Goroutine در حال اجرا است!")
}()

در اینجا، با استفاده از کلمه‌کلیدی go یک Goroutine جدید راه‌اندازی می‌کنیم که به‌طور هم‌زمان اجرا می‌شه.




Channel ها و الگوی ارتباط بین Goroutine ها


Channel‌ها در Go ابزاری برای انتقال داده بین Goroutine‌ها هستند. با استفاده از Channel‌ها می‌توانید داده‌ها رو به‌صورت ایمن و هم‌زمان بین Goroutine‌ها ارسال و دریافت کنید.


ارسال داده به Channel:


ch := make(chan string)
go func() {
ch <- "سلام از Goroutine!"
}()
fmt.Println(<-ch) // دریافت داده از Channel

در اینجا، داده‌ای از یک Goroutine به Channel ارسال می‌شود و در خط بعدی از Channel دریافت می‌شود.




Buffered vs Unbuffered Channels


در Go دو نوع Channel داریم: Buffered و Unbuffered.




  • Unbuffered Channel: این نوع Channel داده‌ها رو بلافاصله از یک Goroutine به دیگری منتقل می‌کنه و بدون منتظر ماندن نمی‌توان داده‌ای را ارسال یا دریافت کرد.




  • Buffered Channel: این نوع Channel می‌تواند تعدادی داده را در خود ذخیره کرده و بعداً ارسال کند. اگر Buffer پر شود، ارسال داده متوقف می‌شود تا فضای کافی برای ذخیره وجود داشته باشد.




مثال:


ch := make(chan string, 2) // Channel با ظرفیت 2
ch <- "سلام"
ch <- "دنیا"
fmt.Println(<-ch) // خروجی: سلام



Select Statement


دستور select در Go این امکان رو به شما می‌ده که با چندین Channel به‌طور هم‌زمان کار کنید و بر اساس وضعیت Channel‌ها عملیات‌های مختلف انجام بدید.


مثال:


select {
case msg1 := <-ch1:
fmt.Println("دریافت پیام از ch1:", msg1)
case msg2 := <-ch2:
fmt.Println("دریافت پیام از ch2:", msg2)
default:
fmt.Println("هیچ پیامی دریافت نشده است.")
}

در اینجا، Go بسته به اینکه کدوم Channel داده‌ای برای دریافت داشته باشه، عملیات مربوطه رو انجام می‌ده.




Mutex و Race Condition


Mutex یک مکانیزم هم‌زمانی در Go است که برای جلوگیری از Race Condition استفاده می‌شود. Race Condition زمانی رخ می‌دهد که دو Goroutine به‌طور همزمان سعی می‌کنند به یک داده دسترسی داشته باشند و باعث خطا یا تغییر غیرمنتظره داده‌ها بشه.


استفاده از Mutex برای جلوگیری از Race Condition:


var mu sync.Mutex
mu.Lock()
// دسترسی ایمن به داده‌ها
mu.Unlock()

با استفاده از Lock و Unlock می‌توانیم از دسترسی هم‌زمان به داده‌ها جلوگیری کنیم.




 WaitGroup و Sync Package


WaitGroup به شما این امکان رو می‌ده که منتظر بمانید تا چندین Goroutine تمام بشن. این ابزار برای همگام‌سازی Goroutine‌ها استفاده میشه.


استفاده از WaitGroup:


var wg sync.WaitGroup
wg.Add(1) // تعداد Goroutine‌هایی که باید منتظرشون بمونیم
go func() {
defer wg.Done() // به محض تمام شدن این Goroutine از WaitGroup کم می‌کنه
fmt.Println("Goroutine تمام شد!")
}()
wg.Wait() // منتظر ماندن تا تمام Goroutine‌ها تمام بشن



Context API در Go


Context در Go برای مدیریت زمان‌های طولانی و محدود کردن زمان انجام عملیات‌های مختلف استفاده می‌شود. به‌طور مثال، می‌توان از آن برای کنترل زمان انقضای درخواست‌ها استفاده کرد.


استفاده از Context:


ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel()
select {
case <-time.After(5 * time.Second):
fmt.Println("کار تمام شد!")
case <-ctx.Done():
fmt.Println("درخواست با خطا مواجه شد:", ctx.Err())
}

در اینجا، با استفاده از Context، اگر مدت زمان تعیین‌شده تمام بشه، عملیات متوقف می‌شه.




در این بخش با مفاهیم هم‌زمانی در Go مانند Goroutine‌ها، Channel‌ها، Mutex‌ها، WaitGroup و Context API آشنا شدیم. با استفاده از این ابزارها، می‌تونید برنامه‌های هم‌زمان و مقیاس‌پذیر بسازید.



نظرات (0)

اشتراک گذاری

این پست را با دیگران به اشتراک بگذارید

تنظیمات GDPR

When you visit any of our websites, it may store or retrieve information on your browser, mostly in the form of cookies. This information might be about you, your preferences or your device and is mostly used to make the site work as you expect it to. The information does not usually directly identify you, but it can give you a more personalized web experience. Because we respect your right to privacy, you can choose not to allow some types of cookies. Click on the different category headings to find out more and manage your preferences. Please note, that blocking some types of cookies may impact your experience of the site and the services we are able to offer.