Concurrency vs Parallelism ใน Golang

Sharing is caring!

บทนำ

หนึ่งในฟีเจอร์ที่ทำให้ภาษา Go โดดเด่นคือความสามารถในการทำงานหลายอย่างพร้อมกันได้ (concurrent) อย่างง่ายดายผ่าน goroutine และ channel แต่หลายคนยังสับสนระหว่างคำว่า Concurrency กับ Parallelism ว่าแตกต่างกันอย่างไร ในบทความนี้เราจะอธิบายความหมาย เปรียบเทียบ และยกตัวอย่างให้เห็นภาพแบบชัดเจนที่สุด

Concurrency คืออะไร?

Concurrency คือความสามารถของโปรแกรมในการ จัดการหลายงาน (tasks) พร้อมกัน โดยอาจจะไม่ได้ทำงานทุกอย่างในเวลาเดียวกันจริง ๆ แต่สามารถสลับไปมาระหว่าง task ได้อย่างมีประสิทธิภาพ

นึกภาพ: คนคนหนึ่งทำหลายอย่างในเวลาใกล้ ๆ กัน เช่น อ่านหนังสือแล้วหยุดมาตอบไลน์ แล้วกลับไปอ่านต่อ

ตัวอย่าง Concurrency ใน Go

func task(name string) {
    for i := 0; i < 3; i++ {
        fmt.Println(name, ":", i)
        time.Sleep(100 * time.Millisecond)
    }
}

func main() {
    go task("A")
    go task("B")
    time.Sleep(1 * time.Second)
}
  

ผลลัพธ์คือ function ทั้ง 2 จะ ทำงานสลับกัน บน thread เดียว

Parallelism คืออะไร?

Parallelism คือความสามารถในการ ทำงานหลายอย่างจริง ๆ ในเวลาเดียวกัน โดยใช้หลาย core ของ CPU

นึกภาพ: คนสองคนอ่านหนังสือพร้อมกันคนละเล่ม

ตั้งค่าการทำ Parallel

โดยปกติ Go จะใช้ parallel ได้อัตโนมัติผ่าน GOMAXPROCS:

runtime.GOMAXPROCS(runtime.NumCPU())
  

ตัวอย่าง Parallel

func compute(n int) {
    sum := 0
    for i := 0; i &lt; 100000000; i++ {
        sum += i
    }
    fmt.Println("Done", n)
}

func main() {
    runtime.GOMAXPROCS(2)
    go compute(1)
    go compute(2)
    time.Sleep(2 * time.Second)
}
  

หากเครื่องมีหลาย core จะเห็นว่า Go ทำงานสอง process นี้พร้อมกันจริง ๆ

เปรียบเทียบ Concurrency vs Parallelism

หัวข้อConcurrencyParallelism
การทำงานจัดการหลายงาน พร้อมกันทำหลายงานในเวลาเดียวกันจริง ๆ
ใช้ CPU กี่ core1 core ก็ได้หลาย core
เหมาะกับแอปที่ต้องรอ IO เช่น HTTPแอปประมวลผลหนัก เช่น ML
ตัวอย่างใน GoGoroutine + ChannelGOMAXPROCS + Goroutine

ภาพประกอบความแตกต่าง

Go มีอะไรช่วยจัดการเรื่องนี้บ้าง?

  • goroutine – หน่วยการทำงานพร้อมกัน
  • channel – ส่งข้อมูลระหว่าง goroutine
  • sync.WaitGroup – รอให้ goroutine ทำงานเสร็จ
  • runtime.GOMAXPROCS – ควบคุมการใช้ core

ตัวอย่างใช้ WaitGroup

var wg sync.WaitGroup

func worker(id int) {
    defer wg.Done()
    fmt.Println("Working:", id)
    time.Sleep(1 * time.Second)
}

func main() {
    wg.Add(2)
    go worker(1)
    go worker(2)
    wg.Wait()
    fmt.Println("All done")
}
  

สรุป

Concurrency คือการออกแบบระบบให้ทำงานพร้อมกันได้ ส่วน Parallelism คือการใช้หลาย CPU ทำงานพร้อมกันจริง ๆ ทั้งสองแนวคิดมีประโยชน์ต่างกันและสามารถใช้ร่วมกันในภาษา Go ได้อย่างมีประสิทธิภาพ

หากคุณเข้าใจทั้ง 2 แนวคิด จะสามารถออกแบบระบบที่เร็วและยืดหยุ่นกว่าเดิมมาก!


บทความโดย: poolsawat.com | เขียนโดย: King Pool

Leave a Reply

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