การดู : 0

12/04/2026 18:17น.

EP.62 การใช้ Context ใน Golang เพื่อจัดการกับการทำงานที่มีการรอคอย (concurrent tasks)

EP.62 การใช้ Context ใน Golang เพื่อจัดการกับการทำงานที่มีการรอคอย (concurrent tasks)

#การทำงานพร้อมกันใน Golang

#การตั้งเวลาใน Golang

#การยกเลิกงานใน Golang

#การจัดการ concurrent tasks ใน Golang

#Concurrent tasks Golang

#Golang context

แพ็กเกจ Context ใน Golang เป็นเครื่องมือที่สำคัญเมื่อเราทำงานกับ concurrent tasks มันช่วยให้เราสามารถจัดการ task ที่รอคอย, จัดการการยกเลิก, และตั้งเวลาให้กับการทำงานที่อาจใช้เวลานาน ในตอนนี้เราจะเรียนรู้วิธีการใช้ context เพื่อควบคุมการทำงานหลายๆ งานพร้อมกันและให้สามารถยกเลิกหรือตั้งเวลาให้กับการทำงานเหล่านั้นได้อย่างมีประสิทธิภาพ การใช้ context จะช่วยให้เราจัดการกับทรัพยากรได้อย่างเหมาะสม และช่วยในการสร้างแอปพลิเคชันที่มีประสิทธิภาพและสามารถขยายตัวได้

 

ทำไม Context ถึงสำคัญ?

แพ็กเกจ Context ใช้สำหรับการจัดการการทำงานที่มีการรอคอยหลายๆ งานพร้อมกัน โดยสามารถ:

  • ยกเลิกงานที่ไม่จำเป็น: เราสามารถยกเลิก task ได้เมื่อไม่ต้องการให้มันทำงาน เช่น เมื่อผู้ใช้ยกเลิกคำขอหรือเมื่อเซิร์ฟเวอร์ปิด
  • ตั้งเวลา: เราสามารถตั้งเวลาให้กับงานที่ทำงานนานเกินไป โดยไม่ให้มันทำงานต่อไปได้
  • ส่งข้อมูลข้าม goroutine: context ช่วยให้เราสามารถส่งข้อมูล (เช่น กำหนดเวลา หรือสัญญาณยกเลิก) ไปยัง goroutine ต่างๆ ได้อย่างสะดวก

ข้อดีของการใช้ Context:

  • การจัดการทรัพยากรที่ดีขึ้น: ช่วยให้เราควบคุมทรัพยากรได้ดีขึ้น และมั่นใจว่าไม่มีการทำงานที่ไม่จำเป็นต่อไป
  • การจัดการ concurrency ได้ง่ายขึ้น: ช่วยให้เราแยกการจัดการงานที่ทำงานพร้อมกันให้ชัดเจนและง่ายต่อการดูแล
  • การยกเลิกและตั้งเวลา: สามารถยกเลิกหรือตั้งเวลาให้กับงานต่างๆ ได้อย่างมีประสิทธิภาพ ช่วยให้การทำงานไม่ถูกบล็อกหรือล่าช้า

 

โครงสร้างการทำงานของ Context

แพ็กเกจ context ใน Golang ออกแบบมาเพื่อส่งสัญญาณการยกเลิก, กำหนดเวลา, หรือส่งข้อมูลข้าม goroutine ระหว่างการทำงานหลายๆ งาน

ส่วนประกอบหลักของ Context:

  1. Context Objects:
    • context.Background() – ใช้เป็น context รากฐาน
    • context.TODO() – ใช้เมื่อไม่แน่ใจว่าจะใช้ context อะไร
    • context.WithCancel() – สร้าง context ที่สามารถยกเลิกได้
    • context.WithTimeout() – สร้าง context ที่มีการตั้งเวลา
    • context.WithDeadline() – สร้าง context ที่มีการตั้งกำหนดเวลา
  2. การยกเลิก:
    • เราสามารถยกเลิก context โดยใช้ cancel() และการยกเลิกนี้จะส่งผลให้ goroutines ที่ใช้ context นั้นได้รับสัญญาณยกเลิก
  3. การตั้งเวลาและกำหนดเวลา:
    • สามารถตั้งเวลาให้กับงานเพื่อป้องกันไม่ให้มันทำงานนานเกินไป

 

วิธีการใช้ Context ในการจัดการกับ Concurrent Tasks

การใช้ context กับหลายๆ concurrent tasks ต้องส่ง context ไปยังทุกๆ goroutine เพื่อให้แต่ละ goroutine สามารถรับสัญญาณการยกเลิกหรือการตั้งเวลา

ขั้นตอนการใช้งาน:

  1. สร้าง Context:
    ใช้ context.Background() หรือ context.TODO() เป็น context รากฐาน
  2. รัน Concurrent Tasks:
    เมื่อสร้าง goroutines ให้ส่ง context ไปให้เพื่อให้แต่ละงานสามารถตรวจสอบการยกเลิกและการตั้งเวลาได้
  3. การยกเลิก:
    ใช้ context.WithCancel() เพื่อสร้าง context ที่สามารถยกเลิกได้ และเมื่อยกเลิก context งานที่เชื่อมโยงกับ context นี้จะได้รับสัญญาณยกเลิก
  4. การตั้งเวลา:
    ใช้ context.WithTimeout() เพื่อตั้งเวลาให้กับการทำงาน ซึ่งจะยกเลิกการทำงานหากงานนั้นใช้เวลานานเกินไป

 

ตัวอย่างโค้ดสำหรับการจัดการ Concurrent Tasks ด้วย Context

  1. การใช้ context ในการยกเลิก Concurrent Tasks

package main

import (
    "context"
    "fmt"
    "time"
)

func task(ctx context.Context, id int) {
    select {
    case <-time.After(2 * time.Second):  // จำลองงานที่ใช้เวลา
        fmt.Printf("Task %d completed\n", id)
    case <-ctx.Done():  // ถ้า context ถูกยกเลิก
        fmt.Printf("Task %d canceled\n", id)
    }
}

func main() {
    ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
    defer cancel()

    for i := 1; i <= 5; i++ {
        go task(ctx, i)
    }

    time.Sleep(4 * time.Second) // รอให้งานเสร็จหรือล้มเหลว
}

ในโค้ดนี้ เราสร้าง context ที่มีเวลา 3 วินาที และถ้างานใช้เวลานานเกินไปมันจะถูกยกเลิก

  1. การใช้ Context กับการยกเลิกสำหรับงานที่ทำงานนาน

package main

import (
    "context"
    "fmt"
    "time"
)

func longRunningTask(ctx context.Context) {
    for {
        select {
        case <-time.After(1 * time.Second):
            fmt.Println("Running task...")
        case <-ctx.Done():  // ตรวจจับการยกเลิก
            fmt.Println("Task canceled")
            return
        }
    }
}

func main() {
    ctx, cancel := context.WithCancel(context.Background())

    go longRunningTask(ctx)

    time.Sleep(3 * time.Second)
    cancel() // ยกเลิกงานหลังจาก 3 วินาที
}

ในตัวอย่างนี้ เราใช้ context.WithCancel() เพื่อยกเลิกงานที่ทำงานนานเกินไป

 

การทดสอบ Concurrent Tasks ด้วย Context

หลังจากที่เราใช้ context แล้ว การทดสอบระบบจะช่วยให้มั่นใจว่า tasks ถูกจัดการได้อย่างมีประสิทธิภาพ

การทดสอบที่ควรทำ:

  • ทดสอบการยกเลิกงาน: ตรวจสอบว่างานสามารถยกเลิกได้เมื่อ context ถูกยกเลิก
  • ทดสอบการตั้งเวลา: ตรวจสอบว่างานที่เกินเวลาจะถูกยกเลิก
  • ทดสอบการซิงโครไนซ์ของ goroutines: ตรวจสอบว่า goroutines ทำงานร่วมกันได้และทำงานตามที่ต้องการเมื่อได้รับสัญญาณยกเลิก

 


 

ท้าให้ลอง!

ลองนำ context ในการจัดการคำขอ HTTP มาจัดการเวลาและยกเลิกคำขอที่ใช้เวลานาน!

 

EP ถัดไป:
ใน EP ถัดไป เราจะมาดู การสร้างระบบการยืนยันตัวตนผู้ใช้ (User Authentication System) สำหรับ WebSocket เพื่อให้ผู้ใช้สามารถยืนยันตัวตนก่อนเข้าร่วมห้องแชท!