การดู : 0

12/04/2026 18:16น.

Ep.18 Go กับ Concurrency ทำหลายอย่างพร้อมกันอย่างลื่นไหล!

Ep.18 Go กับ Concurrency ทำหลายอย่างพร้อมกันอย่างลื่นไหล!

#Superdev School

#โปรแกรมเมอร์

#ภาษาโปรแกรมมิ่ง

#ภาษาโปรแกรม

#ฝึกเขียนโปรแกรม

#การเขียนโปรแกรมสำหรับมือใหม่

#การเขียนโปรแกรม

#การศึกษาการเขียนโปรแกรม

#เทคโนโลยีการเขียนโปรแกรม

#การพัฒนาโปรแกรม

#Channels

#Goroutines

#Concurrency

#ภาษา Go

#Golang

Go กับ Concurrency ทำหลายอย่างพร้อมกันอย่างลื่นไหล!

 

Concurrency คืออะไร?

Concurrency คือความสามารถในการทำงานหลายอย่างพร้อมกัน โดยไม่ต้องรอให้แต่ละงานทำเสร็จทีละงาน เช่น การโหลดข้อมูลขณะรอการตอบสนองจากเซิร์ฟเวอร์ ใน Go เรามี Goroutines ที่ทำให้จัดการ Concurrency ได้ง่าย

 

การทำงานกับ Goroutines

Goroutines เป็นฟังก์ชันใน Go ที่ทำงานแบบเบื้องหลัง เมื่อเราเรียกฟังก์ชันโดยใช้ go ฟังก์ชันนั้นจะเริ่มทำงานเป็น Goroutine ทันที โดยไม่บล็อกโปรแกรมหลัก

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

ในตัวอย่างนี้: ฟังก์ชัน printNumbers จะทำงานเป็น Goroutine ซึ่งทำงานแบบเบื้องหลังโดยไม่บล็อก main()

package main

import (
    "fmt"
    "time"
)

func printNumbers() {
    for i := 1; i <= 5; i++ {
        fmt.Println(i)
        time.Sleep(500 * time.Millisecond)
    }
}

func main() {
    go printNumbers() // เริ่ม Goroutine
    fmt.Println("Goroutine started")
    time.Sleep(3 * time.Second) // รอให้ Goroutine ทำงานเสร็จ
}

 

การสื่อสารระหว่าง Goroutines ด้วย Channels

Channels คือเครื่องมือสำหรับส่งข้อมูลระหว่าง Goroutines ทำให้เราสามารถควบคุมการทำงานของ Goroutines และส่งข้อมูลระหว่างกันได้

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

ในตัวอย่างนี้:

ch := make(chan string) สร้าง Channel สำหรับส่งข้อมูลแบบข้อความ

ch <- "Hello from Goroutine" ส่งข้อความจาก Goroutine ไปยัง Channel

msg := <-ch รับข้อความจาก Channel และพิมพ์ข้อความนั้นออกมา

package main

import (
    "fmt"
)

func printMessage(ch chan string) {
    ch <- "Hello from Goroutine" // ส่งข้อความผ่าน Channel
}

func main() {
    ch := make(chan string)

    go printMessage(ch)

    msg := <-ch // รับข้อความจาก Channel
    fmt.Println(msg)
}

 

Buffered Channels - จัดเก็บข้อมูลหลายค่าก่อนนำไปใช้งาน

Buffered Channels ช่วยให้เราส่งข้อมูลได้หลายค่าใน Channel ก่อนนำไปใช้งาน ช่วยเพิ่มประสิทธิภาพและลดการรอคิวข้อมูล

ตัวอย่างการใช้งาน Buffered Channel:

ในตัวอย่างนี้:

Channel ch ถูกสร้างให้เก็บได้ 3 ค่า

ข้อมูลทั้งหมดจะถูกส่งเข้า Channel แล้วดึงออกมาทีละค่าโดยไม่มีการรอคิว

package main

import (
    "fmt"
)

func main() {
    ch := make(chan int, 3) // Channel ที่เก็บข้อมูลได้ 3 ค่า

    ch <- 1
    ch <- 2
    ch <- 3

    fmt.Println(<-ch) // แสดงค่า 1
    fmt.Println(<-ch) // แสดงค่า 2
    fmt.Println(<-ch) // แสดงค่า 3
}

 

การใช้ select สำหรับจัดการหลาย Channels

ในกรณีที่เรามีหลาย Channel select ช่วยให้เราสามารถจัดการการสื่อสารระหว่าง Channel ได้ง่ายขึ้น

ตัวอย่างการใช้ select กับ Channel:

ในตัวอย่างนี้:

โปรแกรมจะรอจนกว่าจะมีข้อมูลจาก Channel ใด Channel หนึ่งพร้อมใช้งาน

select ช่วยให้เราสามารถจัดการการรับส่งข้อมูลระหว่าง Channel หลายตัวได้อย่างมีประสิทธิภาพ

package main

import (
    "fmt"
    "time"
)

func main() {
    ch1 := make(chan string)
    ch2 := make(chan string)

    go func() {
        time.Sleep(2 * time.Second)
        ch1 <- "Message from channel 1"
    }()

    go func() {
        time.Sleep(1 * time.Second)
        ch2 <- "Message from channel 2"
    }()

    select {
    case msg1 := <-ch1:
        fmt.Println(msg1)
    case msg2 := <-ch2:
        fmt.Println(msg2)
    }
}

 

สรุปง่ายๆ

  • ใช้ go เพื่อเริ่ม Goroutine ทำงานเบื้องหลัง
  • ใช้ Channel เพื่อส่งข้อมูลระหว่าง Goroutines
  • ใช้ Buffered Channels สำหรับเก็บข้อมูลหลายค่าก่อนใช้งาน
  • ใช้ select เพื่อจัดการการทำงานระหว่างหลาย Channels

ลองสร้างโปรแกรมที่ใช้ Goroutines และ Channel เพื่อจำลองการรับข้อความจากผู้ใช้หลายคน พร้อมเก็บข้อความที่ได้รับใน Channel และแสดงผลลัพธ์ทีละข้อความตามลำดับ!