ทำความเข้าใจ Goroutine และ Channel แบบง่าย ๆ

Sharing is caring!

Goroutine คืออะไร?

Goroutine คือกลไกที่ Go ใช้เพื่อจัดการงานหลายอย่างพร้อมกัน (Concurrency) ได้อย่างมีประสิทธิภาพ โดยใช้ memory น้อยและไม่ต้องจัดการ thread ด้วยตนเอง

เราสามารถเริ่ม goroutine ได้ง่าย ๆ ด้วยคำว่า go หน้าชื่อฟังก์ชัน

go sayHello()

ตัวอย่าง: การใช้ Goroutine

package main

import (
    "fmt"
    "time"
)

func sayHello() {
    for i := 0; i < 5; i++ {
        fmt.Println("Hello from Goroutine")
        time.Sleep(500 * time.Millisecond)
    }
}

func main() {
    go sayHello() // run as goroutine

    for i := 0; i < 5; i++ {
        fmt.Println("Main function running")
        time.Sleep(700 * time.Millisecond)
    }
}
  

ผลลัพธ์: โค้ดนี้จะแสดงข้อความจากฟังก์ชันหลักและ goroutine สลับกันแสดง (ขึ้นกับ scheduler)

Channel คืออะไร?

Channel คือเครื่องมือที่ Go ใช้สำหรับการสื่อสารระหว่าง goroutine อย่างปลอดภัย โดยทำงานแบบ blocking โดย design

การสร้างและส่งค่าผ่าน channel

ch := make(chan string) // สร้าง channel สำหรับ string
  
go func() {
    ch &lt;- "Hello from goroutine" // ส่งค่าเข้า channel
}()

msg := &lt;-ch // รับค่าออกจาก channel
fmt.Println(msg)
  

ผลลัพธ์: โปรแกรมจะรอรับค่าก่อนจะไปบรรทัดถัดไป

Buffered Channel

channel แบบ buffer ช่วยให้ส่งค่าได้โดยไม่ block ทันที:

ch := make(chan int, 2) // buffered channel

ch &lt;- 1
ch &lt;- 2
// ch &lt;- 3 // ถ้าเพิ่มอีกจะ block จนกว่าจะมีการรับ

fmt.Println(&lt;-ch)
fmt.Println(&lt;-ch)
  

ภาพประกอบการทำงาน

ปิด Channel อย่างไร?

สามารถใช้ close(channel) เพื่อระบุว่า channel นี้จะไม่มีการส่งข้อมูลแล้ว เช่น:

close(ch)

การใช้กับ range:

for msg := range ch {
    fmt.Println(msg)
}
  

Select ใน Channel

ใช้เพื่อรอหลาย channel พร้อมกัน:

select {
case msg1 := &lt;-ch1:
    fmt.Println("Received", msg1)
case msg2 := &lt;-ch2:
    fmt.Println("Received", msg2)
default:
    fmt.Println("ไม่มีอะไรมาเลย")
}
  

Goroutine Leak คืออะไร?

หาก goroutine ถูกสร้างขึ้น แต่ไม่สามารถออกจาก function ได้ หรือรอบางสิ่งที่ไม่มีวันเกิดขึ้น จะเกิดปัญหา memory รั่วได้

แนวทางป้องกัน:

  • ใช้ timeout หรือ context
  • ควบคุมการปิด channel อย่างเป็นระบบ

สรุป

  • Goroutine: เบา ใช้ง่าย สร้างได้มาก
  • Channel: ใช้ส่งข้อมูลระหว่าง goroutine อย่างปลอดภัย
  • ควรเรียนรู้: select, buffered channel, close, range

หากคุณเข้าใจแนวคิดพื้นฐานเหล่านี้แล้ว การเขียน concurrent system ด้วย Go จะง่ายกว่าที่เคย!


บทความนี้เผยแพร่โดย: poolsawat.com | เขียนโดย: King Pool

Leave a Reply

อีเมลของคุณจะไม่แสดงให้คนอื่นเห็น ช่องข้อมูลจำเป็นถูกทำเครื่องหมาย *