Threads
ในบทนี้ คุณจะได้เรียนรู้เกี่ยวกับการใช้งาน Thread ในภาษา Visual Basic เราจะมาสร้างโปรแกรมที่สามารถทำงานได้พร้อมกันหลาย Thread หรือการเขียนโปรแกรมแบบ Multithreading
Thread คืออะไร
เมื่อโปรแกรมเริ่มทำงาน Common language runtime (CLR) จะทำการสร้าง Thread หนึ่งขึ้นมาอัตโนมัติ เราเรียกว่า Thread หลักหรือ Main thread ของโปรแกรม โดยมันจะทำงานอยู่เบื้องหลัง ในภาษา Visual Basic คุณสามารถสร้าง Thread ได้หลายๆ Thread โดยแต่ละ Thread จะทำงานแบบไม่พร้อมกัน (Asynchronous)
ข้อได้เปรียบในการใช้ Thread คือการที่โปรแกรมสามารถทำงานได้พร้อมกันหลายๆ อย่าง ยกตัวอย่างเช่น คุณต้องการล้างรถและซักผ้า คุณจะต้องทำอย่างหนึ่งให้เสร็จจึงจะทำสิ่งต่อไปได้ ในขณะที่ใช้ Thread คุณจะสามารถล้างรถและซักผ้าพร้อมกันได้
Thread มักจะนำไปใช้กับโปรแกรมที่ต้องทำงานพร้อมกันเพื่อให้มีประสิทธิภาพสูงสุด เช่น Parallel programming, Multi-core programming หรือในงานที่สามารถแบ่งงานกันทำได้ เช่น โปรแกรมสำหรับ Render วิดีโอสามารถให้แต่ละ Thread ทำงานแต่ละส่วนค่อยนำมารวมกันได้ ซึ่งทำให้เพิ่มความเร็วขึ้นมาสำหรับ Multi-core programming
การสร้าง Thread
ต่อไปมาดูตัวอย่างการสร้าง Thread ในภาษา Visual Basic โดยการทำงานของ Thread นั้นมักจะเกี่ยวข้องกับ Delegates ในการกำหนดฟังก์ชันสำหรับการทำงานของ Thread
Imports System.Threading
Module ThreadExample
Sub Main()
Dim trd As New Thread(AddressOf ThreadTask)
trd.IsBackground = False
trd.Start()
End Sub
Sub ThreadTask()
Console.WriteLine("This message from a thread")
End Sub
End Module
ในตัวอย่าง เป็นการสร้าง Thread อย่างง่ายจากคลาส Thread
โดยคลาสนี้ให้เราจัดการสิ่งๆ ต่างเกี่ยวกับ Thread ได้ทั้งหมด
Dim trd As New Thread(AddressOf ThreadTask)
ในคำสั่งแรก เป็นการสร้างตัวแปร Thread trd
เราใช้ Delegate ในการกำหนดฟังก์ชัน ThreadTask()
ให้เป็นฟังก์ชันการทำงานของ Thread ดังกล่าว
trd.IsBackground = False
trd.Start()
เรากำหนดค่า False
ให้กับ property IsBackground
หมายความว่าให้ Thread นี้ไม่ทำงานในเบื้องหลัง โดยพื้นฐานมันมีค่าเป็น False อยู่แล้ว หลังจากนั้นเรียกใช้เมธอด trd.Start()
สำหรับเริ่มการทำงานของ Thread
This message from a thread
นี่เป็นผลลัพธ์ของโปรแกรม ซึ่ง Thread จะทำงานในฟังก์ชันที่เราได้กำหนดให้กับมันในตอนแรก
เพื่อหยุดการทำงานของ Thread คุณสามารถใช้เมธอด trd.Abort()
แต่สำหรับในตัวอย่างเมื่อ Thread ทำงานเสร็จสิ้นแล้วมันจะปิดการทำงานโดยอัตโนมัติ เพราะว่าการทำงานในฟังก์ชัน ThreadTask()
ของเราไม่ได้เป็นแบบ Infinity loop
การเขียนโปรแกรมแบบ Multithreading
ในตัวอย่างก่อนหน้า คุณได้รู้วิธีการสร้าง Thread ไปแล้ว ต่อไปเราจะมาเขียนโปรแกรมที่ใช้ความสามารถของ Thread อย่างแท้จริงคือการใช้หลายๆ Thread ในการทำงานหลายอย่างพร้อมๆ กัน
Imports System.Threading
Module MultithreadExample
Dim trdRead As Thread
Dim trdSend As Thread
Sub Main()
trdRead = New Thread(AddressOf ThreadRead)
trdRead.Start()
trdSend = New Thread(AddressOf ThreadSend)
trdSend.Start()
End Sub
Sub ThreadRead()
While True
Console.WriteLine("Read data from network stream")
Thread.Sleep(2000)
End While
End Sub
Sub ThreadSend()
While True
Dim c As Char = Console.ReadKey().KeyChar
Console.WriteLine("Send {0} to network stream ", c)
If c = "0"c Then
trdRead.Abort()
trdSend.Abort()
End If
End While
End Sub
End Module
ในตัวอย่าง เราได้เขียนโปรแกรมสำหรับจำลองการส่งข้อมูลใน Network โดยเราสร้าง Thread สำหรับการส่งข้อมูลและรับข้อมูล
Dim trdRead As Thread
Dim trdSend As Thread
เราประกาศตัวแปร Thread สำหรับการรับข้อมูลและการส่งข้อมูลตามลำดับ
trdRead = New Thread(AddressOf ThreadRead)
trdRead.Start()
trdSend = New Thread(AddressOf ThreadSend)
trdSend.Start()
เรากำหนดฟังก์ชันการทำงานให้กับ Thread และสั่งให้ Thread เริ่มทำงาน เมื่อสิ้นสุดคำสั่งนี้ ฟังก์ชันทั้งสองจะทำงานไปพร้อมๆ กัน
Sub ThreadRead()
While True
Console.WriteLine("Read data from network stream")
Thread.Sleep(2000)
End While
End Sub
ในฟังก์ชัน ThreadRead()
เป็นการจำลองรับข้อมูลจาก Network ในทุกๆ สองวินาที เมธอด Thread.Sleep()
สำหรับหน่วงเวลาการทำงานของโปรแกรมในหน่วนมิลลิวินาที
Sub ThreadSend()
While True
Dim c As Char = Console.ReadKey().KeyChar
Console.WriteLine("Send {0} to network stream ", c)
If c = "0"c Then
trdRead.Abort()
trdSend.Abort()
End If
End While
End Sub
ในฟังก์ชัน ThreadSend()
เป็นการจำลองส่งข้อมูลไปใน Network โดยรับค่าทางคีย์บอร์ดและส่งไปทันที เรายังตรวจสอบถ้าหากค่าที่รับมานั้นเป็น 0 เราจะหยุดการทำงานของ Thread ทั้งหมด
Read data from network stream
Read data from network stream
Read data from network stream
aSend a to network stream
Read data from network stream
Read data from network stream
bSend b to network stream
Read data from network stream
Read data from network stream
Read data from network stream
3Send 3 to network stream
Read data from network stream
0Send 0 to network stream
นี่เป็นผลลัพธ์การทำงานของโปรแกรม ซึ่งโปรแกรมจะแสดงข้อความ Read data from network stream ทุกๆ สองวินาที ในขณะเดียวกันเรายังสามารถรับค่าจากคีย์บอร์ดเพื่อที่จะส่งข้อมูลได้ และ Thread ทั้งสองจะหยุดการทำงานเมื่อกดปุ่ม 0
Passing parameters to thread
ในตัวอย่างก่อนหน้า เราได้ใช้ Delegate ในการกำหนดฟังก์ชันการทำงานให้กับ Thread ต่อไปเราจะส่งพารามิเตอร์ไปยัง Thread เพื่อนำค่าไปใช้งานภายใน Thread
Imports System.Threading
Module ThreadParameters
Sub Main()
For i = 1 To 10
Dim p As New Parameter
p.number = i
Dim thr As New Thread(AddressOf DispayNumber)
thr.Start(p)
Next
End Sub
Sub DispayNumber(ByVal param As Parameter)
Console.WriteLine("Thread " & param.number)
End Sub
End Module
Class Parameter
Public number As Integer
End Class
ในตัวอย่างเราได้สร้างคลาส Parameter
สำหรับเป็นพารามิเตอร์ในการส่งข้อมูลเข้าไปใน Thread เราใช้คำสั่ง For loop ในการสร้าง 10 Thread ขึ้นมา
thr.Start(p)
นี่เป็นคำสั่งที่เราส่งออบเจ็ค p
ซึ่งประกอบไปด้วยหมายเลขของ Thread โดยใส่เป็นพารามิเตอร์ของเมธอด thr.Start()
และในฟังก์ชัน
Thread 1
Thread 4
Thread 3
Thread 2
Thread 5
Thread 6
Thread 7
Thread 8
Thread 9
Thread 10
นี่เป็นผลลัพธ์การทำงานของโปรแกรม ซึ่งตัวเลขจะไม่เรียงลำดับเพราะว่าการทำงานในแต่ละ Thread นั้นอาจจะใช้เวลาแตกต่างกัน ซึ่งขึ้นกับการทำงานของคอมพิวเตอร์ในตอนนั้น
นี่เป็นเพียงแค่ตัวอย่างพื้นฐานของ Thread เท่านั้น ซึ่งการทำงานกับ Thread นั้นมีเรื่องที่คุณจะต้องศึกษาอีกมากมาย เพราะว่า Thread นั้นทำงานพร้อมกัน มันเป็นไปได้ที่จะเกิดการอ่านหรือเขียนข้อมูลในเวลาเดียวกัน (Race condition) ซึ่งใน .Net framework ได้มีไลบรารี่มาตรฐานสำหรับจัดการเช่น Mutexes, Condition variables, Critical sections, Semaphores หรือวิธีอื่นๆ
ในบทนี้ คุณได้เรียนรู้และเข้าใจเกี่ยวกับการใช้งาน Thread ในภาษา Visual Basic และแนวคิดการพัฒนาโปรแกรมแบบ Multithreading