DEV Community

ksupdev
ksupdev

Posted on

Golang : ลำดับในการเรียกใช้งาน Goroutines

#go

Goroutines คือ Goroutines are functions or methods that run concurrently with other functions or methods.

จากข้อความอันนี้ผมว่าก็น่าจะค่อนข้างชัดเจนระดับหนึ่งเลยซึ่งผมเลยคิดว่าไม่น่าจะต้องอธิบายเพิ่มแล้วนะครับ แต่ถ้าใครไม่เข้าใจ ผมแนะนำนี้เลยครับ tour of go

โจทย์วันนี้

พอผมได้ลองศึกษา การทำงานแบบ concurrent โดยใช้ goroutine และจากที่ผมได้เห็นตัวอย่างจากหลายๆ project พบว่ามีการเขียน run func ด้วย goroutines และใน function นั้นเองก็มีการเรียกใช้งาน anonymous function ด้วย goroutines จึงทำให้เริ่มส่งสัยว่า การเรียกใช้งานซ้อนๆกันแบบนี้ มันจะมีลำดับการทำงานยังไง

ผมก็เลยลองทำตัวอย่างง่ายๆเพื่อทดสอบ

สมมติฐานเบื้องต้น

ผมเคยคิดว่ามันก็น่าจะทำงานตามลำดับในการเรียก อย่างเช่น goruntine ในสุดอาจจะต้องทำงานก่อนให้เสร็จแล้วค่อยมาทำในลำดับชั้นถัดไป ซึ่งไม่น่าจะทำงานพร้อมกัน บอกเลยครับก่อนจะทำทดสอบดู ก็คิดแบบนี้เลยแล้วพอไปอ่าน ตัวอย่าง project งง หนักเลย ^^

เริ่มทดสอบกันหน่อย

func main() {
    ...
    inputData := "123"

    go func1(inputData, startTime)

    go func2(inputData, startTime)

    //anonymous
    go func(s string) {go func3(s, startTime)}(inputData)
}

func func1(s string, startTime time.Time) {...}

func func2(s string, startTime time.Time) {...}

func func3(s string, startTime time.Time) {...}

Enter fullscreen mode Exit fullscreen mode

ผมทำการสร้าง func เพื่อจำลองการทำงานทั้งหมด 4 function ซึ่งประกอบไปด้วย

func main จะเรียกใช้งาน func1, func2 นอกจากนี้ยังมีการสร้าง anonymous func ซึ่งจะใช้ในการ call func3 โดยทั้งหมดจะ run แบบ goroutine หรือก็คือให้ทั้งหมดมีการทำงานพร้อมกันนั้นเอง

เพื่อขยายความเข้าใจของคำว่าทำงานพร้อมกันผมจะลอง run program แบบไม่ใช่ goroutine หรือก็แค่ผมเอาคำว่า go ออกตอนเรียกใช้งาน function นั้นเอง

output run without goroutine

---- Start program ---- [0s] 
func1 output = 1      [10ms]
func1 output = 2      [20ms]
func1 output = 3      [30ms]
func2 output = 1      [40ms]
func2 output = 2      [50ms]
func2 output = 3      [60ms]
func3 output = 1      [70ms]
func3 output = 2      [80ms]
func3 output = 3      [90ms]
Anonymus-1 output = 1 [100ms]
Anonymus-1 output = 2 [110ms]
Anonymus-1 output = 3 [120ms]
---- End progra ---- [1.12s] 
Enter fullscreen mode Exit fullscreen mode

จะเห็นว่าผลเป็นไปตามที่ผมคิดเลย ^^

ซึ่งก็คือจะทำงานตามลำดับในการเรียกใช้งานเลย และถ้าสังเกตุดีๆจะเห็นว่า func3 ที่ถูกเรียกโดย anonymus function จะมีการทำงานเรียกตามลำดับในการเรียก หรือการเขียน program แบบทั่วๆไปนั้นเอง

และคราวนี้ผมจะ run แบบใช้ goroutine

output run with goroutine

--------- Start program ---- [0s] 
func3 output = 1      [10ms]
Anonymus-1 output = 1 [10ms]
func1 output = 1      [10ms]
func2 output = 1      [10ms]
Anonymus-1 output = 2 [20ms]
func3 output = 2      [20ms]
func2 output = 2      [20ms]
func1 output = 2      [20ms]
func3 output = 3      [30ms]
Anonymus-1 output = 3 [30ms]
func1 output = 3      [30ms]
func2 output = 3      [30ms]
--------- End progra ---- [1s] 
Enter fullscreen mode Exit fullscreen mode

จากผลที่ได้เราจะเห็นว่า func1, func2, func3, Anonymus-1 นั้นจะทำงานพร้อมกันในทันที หรืออาจจะพูดได้ว่าแถบจะไม่สนใจลำดับในการเรียกใช้งานเลย ไม่ว่าจะเรียกโดยตรงจาก main หรือ ถูกเรียกจากอีก goroutine ก็คาม

Example project ซึ่งๆเพื่อนๆสามารถไปลองกันได้เลยครับ

play.golang.org

อันนี้เป็นบทความที่ 2 ถ้าผมผิดพลาดยังไงเพื่อนๆสามารถแนะนำได้นะครับ

ขอบคุณครับ

Latest comments (0)