เขียน Goroutine อย่างง่าย
Feb 21, 2025
วันนี้ผมจะมาสอนเขียน Goroutine แบบง่าย ๆ กัน
เริ่มแรกเลยคือ เราต้องมาทำความรู้จักกับ Goroutine กันก่อน
Goroutine คืออะไร
Goroutine ใน Golang คือ lightweight thread ที่ทำให้โค้ดสามารถทำงานแบบ concurrent ได้
การสร้าง Goroutine สามารถทำได้โดยใช้ keyword "go" หน้า function ที่ต้องการให้ทำงานแบบ concurrent
ตัวอย่างเช่น
เป็นโปรแกรมง่ายๆ ที่ print "Hello, Goroutine!" จากฟังก์ชั่น sayHello
และ print "Hello, Main!" จาก main
ผลลัพธ์ที่ได้ แน่นอนว่าจะออกมาเป็น
เพราะมีการเรียก sayHello ก่อน
ทีนี่ถ้าเราลองปรับด้วยการเรียก sayHello ด้วย keyword go เพื่อเรียก sayHello ด้วย Goroutine ใหม่
จะได้ผลลัพธ์เป็น
สังเกตุว่าจะไม่เห็นไม่มี "Hello, Goroutine!" แสดงออกมา
นั่นก็เป็นเพราะ sayHello ทำงานที่อีก Goroutine นึง ทำให้ main function ไม่ได้รอให้ sayHello print ก่อน จึง exit program
วิธีแก้ปัญหาแบบง่ายๆ คือ เพิ่ม time.Sleep เพื่อให้ main function รอ sayHello ทำงานเสร็จก่อน
ผลลัพธ์จากการรันโปรแกรมจะได้
แต่อย่างไรก็ตามวิธีการใช้ time.Sleep จะใช้ได้ผลก็ต่อเมื่อเราแน่ใจได้ว่า sayHello นั่นทำงานเสร็จทัน 1 second ตามที่เรา time.Sleep รอเอาไว้
ลองยกตัวอย่างการทำงานของ sayHello ที่ทำงานนานกว่า 1 second
แน่นอน ว่าจะได้ผลลัพธ์เป็น
เพราะ main function นั้นเสร็จก่อน sayHello ทำงานเสร็จ
อีกวิธีแก้คือใช้ sync.WaitGroup ในการส่งสัญญานบอกการทำงานเสร็จของ Goroutine
ตัวอย่างเช่น
ในตัวอย่างนี้เรามีการประกาศ
เพื่อใช้ในการส่งสัญญานการทำงานเสร็จของ Goroutine
มีการเรียก
คือเป็นการเพิ่ม counter ให้ WaitGroup เพื่อบอกว่ามี Goroutine ที่ต้องรอ (Wait) จำนวน 1 ตัว
หลังจากนั้นเราก็ส่ง &wg เข้าไปยัง Goroutine sayHello
ในส่วนของ sayHello function เราก็มีการเรียก
เพื่อเป็นการสงสัญญาณบอก WaitGroup ว่า Goroutine ตัวนั้นทำงานเสร็จแล้ว โดยเมื่อเรียก Done ตัว Counter จะลดไป 1
การใช้ defer เพื่อเป็นการ execute หลัง function ทำงานเสร็จ
กลับมาที่ main function
เรามีการเรียด Wait หลัง print เพื่อเป็นการรอให้ Couter ของ WaitGroup เป็น 0 ก่อนทำงานต่อ นั่นคือการรอให้ Goroutine ทำงานเสร็จก่อนนั่นเอง
ผลลัพธ์ที่ได้คือ
โดยที่ไม่ต้องใช้ time.Sleep และไม่ว่า Goroutine จะทำงานนานแค่ไหน ก็เป็นการการันตีว่า Main function จะรอเสมอ