9.4.14 الگو Pipeline

9.4.14 الگو Pipeline

9.4.14.1 توضیحات #

الگو خط لوله (Pipeline) یکی از پرکاربردی ترین الگوها در همزمانی می باشد شما با استفاده از این الگو می توانید تسک های بزرگ را به تسک های کوچکتر و مستقل تقسیم کنید که می توانند بطور همزمان کار کنند. هر stage داخل یک گوروتین انجام می شود و بواسطه کانال داده ها بین stage های مختلف منتقل می شود.

9.4.14.2 دیاگرام #

pipeline

9.4.14.3 نمونه کد #

 1package main
 2
 3import "fmt"
 4
 5func gen(nums ...int) <-chan int {
 6	out := make(chan int)
 7	go func() {
 8		defer close(out)
 9		for _, n := range nums {
10			out <- n
11		}
12	}()
13	return out
14}
15
16func sq(in <-chan int) <-chan int {
17	out := make(chan int)
18	go func() {
19		defer close(out)
20		for n := range in {
21			out <- n * n
22		}
23	}()
24	return out
25}
26
27func main() {
28	// Set up the pipeline.
29	c := gen(2, 3)
30	out := sq(c)
31
32	// Consume the output.
33	fmt.Println(<-out) // 4
34	fmt.Println(<-out) // 9
35}
1$ go run main.go
24
39

در مثال فوق ما یک قصد داریم اعدادی را مربع کنیم :

  • در stage اول تابع gen لیست اعدادی را به عنوان ورودی دریافت می کنند و سپس داخل کانال قرار می دهد و سپس کانال فقط دریافت را بازگشت می دهد.
  • در stage دوم تابع sq کانال فقط دریافتی را به عنوان ورودی میگیرد سپس از طریق کانال اعداد را دریافت می کنیم و اعداد را مربع می کنیم و به کانال می فرستیم و در نهایت کانال را بازگشت می دهیم.
  • تابع main شروع کننده Pipeline ما می باشد که در ابتدا اعداد را به تابع gen میفرست و یک کانال فقط دریافت می دهد و این کانال را به stage دوم تابع sq پاس می دهیم تا اعداد مربع شوند. و در آخر از طریق کانال مقادیر مربع شده را می توانیم دریافت کنیم و نمایش دهیم.

نکات مهم :

  1. در الگو Pipeline مرحله (stage) اول فقط داده هایی که قرار است عملیات را انجام دهیم پاس می دهیم.
  2. در سایر stage های به عنوان ورودی و خروجی کانال فقط دریافتی به عنوان پارامتر قرار می دهیم.
  3. گوروتین داخل هر stage اجرا می شود و از تابع inline استفاده می کنیم.
  4. کانال را داخل گوروتین داخل defer قرار دهید که پس از عملیات کانال بسته شود.
  5. از context می توانید برای کنترل عملیات داخل هر stage استفاده کنید, به عنوان مثال اگر قصد داشته باشید عملیاتی را که هر stage هست متوقف کنید کافیه از context استفاده کنید تا کنترل بیشتری داشته باشید.

یک مثال کاربردی دیگر

9.4.14.4 کاربردها #

  • شبکه : یک Pipeline می تواند برای مدیریت چندین اتصال شبکه ورودی با عبور از چندین مرحله مانند تجزیه، فیلتر کردن و مسیریابی استفاده شود.
  • محاسبات چند مرحله ای: یک Pipeline می تواند برای انجام یک سری محاسبات روی داده های ورودی استفاده شود که در آن خروجی یک مرحله به عنوان ورودی برای مرحله بعدی استفاده می شود.
  • پردازش گزارش: یک Pipeline می تواند برای پردازش داده های گزارش با عبور دادن آنها از مراحل مختلف مانند فیلتر کردن، تجزیه، غنی سازی و نمایه سازی استفاده شود.
  • تجزیه و تحلیل داده ها: یک Pipeline می تواند برای پردازش مجموعه داده های بزرگ با عبور از مراحل مختلف مانند فیلتر کردن، نقشه برداری و کاهش استفاده شود.