abbas80
abbas80
خواندن ۲ دقیقه·۵ ماه پیش

نگاهی مختصر به concurrency در Go: مقدمه

همزمانی یا همان concurrency بطور کلی اجرای کدها بصورت غیر خطی است و در زبان کو براحتی می توان از آن استفاده کرد.

یعنی وقتی اجرای دستوری زمان بگیرد برنامه مون بخاطرش موفق نمی شود و به اجرای دستورات بعدی می رود٬ بعدا با مثال بیشتر آشنا خواهید شد

زبان گو concurrency را با goroutines (گوروتین ها) هندل می کند٬ گوریتین ها مزایای زیادی نسبت به ترد های سیستم عامل دارد مثلا: حجم کمتر٬ سربار کمتر٬ پیاده سازی آسانتر٬ سرعت پیشتر و ...

حالا چجوری این گوروتین ها رو پیاده سازی کنیم؟

کیورد go

اول یک برنامه معمولی می نویسیم

package main import &quotfmt&quot func count(n int) { for i := 0; i < n; i++ { fmt.Println(i, n) time.Sleep(500 * time.Millisecond) } } func main() { count(3) }


مثل آب خوردن فقط کافیه اول خط کلمه کلیدی go را اضافه کنیم!

func main() { go count(3) // just this }
هیجی !!
هیجی !!


همانطور که می بینید هیج خروجی نشان نداد ؛/ چون هر برنامه توسظ یک گوروتین اصلی (main) اجرا می شود و هنگامی که کارش تمام می شود گوروتین های دیگه هم متوقف می کند.

فعلا دستی خودمون حلش می کنیم تا ببینیم چی میشه :|

func main() { go count(3) time.Sleep(2*time.Second) // ok ;) }

خب٬ بعدش یک goroutine دیگه اضافه می کنیم

func main() { go count(3) go count(5) time.Sleep(5*time.Second) // just to make sure; }

شما می تونید (به همین اسونی) ترد اضافه کنید اما٬ راه حلی بهتر از رفع این باگ وجود دارد؟

sync/WaitGroup


package main import ( &quotfmt&quot &quotsync&quot &quottime&quot ) func count(n int) { for i := 0; i < n; i++ { fmt.Println(i, n) time.Sleep(200 * time.Millisecond) } } func main() { var wg sync.WaitGroup wg.Add(1) go func() { defer wg.Done() count(4) }() wg.Wait() }

ابتدا ما پکیج sync را وارد کردیم٬ سپس در تابع main یک متغیر از sync.WaitGroup ساختیم و با متد Add٬ تعداد گوروتین ها را مشخض کردیم (این به این معنیست که ما منتظر چند گوروتین هستیم) بعد ما خط فراخوانی تابع را بصورت یک تابع ناشناس درآوردیم تا همونجا از آن استفاده کنیم بعد به صورت defer متد Done از wg را صدا میزنیم تا بفهمانیم کارمون تموم شده ودر آخر متد wg.Wait را برای منتظر ماندن گوروتین main سدا زدیم.

کار waitGroup اینه که فرایند main در حال اجرا نگه دارد تا مانع اتمام برنامه شود٬ ولی اگه خواستیم از توابع دادهی را رد و بدل چاره چیست؟


خب كار با چنل ها و چیز های دیگه رو در پست بعدی مشاهده خواهید کرد ولی تا اینجا رسیدیم بد نیست یک جمع بندی انجام بدیم

جمع بندی

زبان گو برای کارهای همزمانی (concurrency) زبان جمع و جوری است بخصوص با ویژگی خفن گوروتین ها (goroutines) میشه براحتی انرا پیاده سازی کرد٬ از ویژگی های دیگر گولنگ WaitGroup است که مانع پایان یافتن گوروتین اصلی قبل گوروتین های دیگه است


خب امیدوارم مطلب مفید باشد٬ تا وقتی دیگر بدرود :-)


goconcurrencyگولنگهمزمانیsync waitgroup
شاید از این پست‌ها خوشتان بیاید