Thread Trong C# – Transinhs
Có thể bạn quan tâm
THREAD
Định nghĩa:
- Thread hay còn gọi là tiểu trình.
- Thread cho phép chương trình thực hiện đồng thời nhiều tác vụ, và giúp quá trình tương tác với người dùng không bị gián đoạn, lập trình song song và là kĩ thuật không thể thiếu trong các ứng dụng về mạng
- Bạn không nên nhầm lẫn giữa process (tiến trình) và thread (tiểu trình). Process có thể hiểu là một instance của chương trình máy tính được thực thi, dựa trên hệ điều hành, hoàn toàn độc lập với các tiến trình khác. Còn thread là một nhóm lệnh được tạo ra để thực thi một tác vụ trong một process, chúng chia sẻ chung dữ liệu với nhau để xử lý, điều này là cần thiết nhưng cũng là nguyên nhân dễ gây ra lỗi nếu bạn không xử lý đúng cách.
- Tạo phương thức (gọi là phương thức callback) sẽ thực thi ghi thread được gọi: Phương thức này phải không có tham số hoặc chỉ có một tham số là kiểu object và kiểu trả về là void. Bước này có thể bỏ qua vì ta có thể sử dụng sử dụng anonymous methodhoặc lambda expression để tạo đoạn mã lệnh thực thi in-line cùng với lệnh khởi tạo thread.
- Tạo đối tượng Thread và truyền một delegate ThreadStart chứa phương thức sẽ thực thi vào constructor của Thread.
- Chạy thread: Gọi phương thức Start() của đối tượng thread vừa tạo.
Tạo và thực thi thread
class DemoThread1
{
public static int n = 100000;
public void Demo()
{
Thread t = new Thread(new ThreadStart(MethodA));
t.Start();
MethodB();
Console.ReadLine();
}
public void MethodA()
{
for (int i = 0; i < n; i++)
Console.Write(“0”);
}
public void MethodB()
{
for (int i = 0; i < n; i++)
Console.Write(“1”);
}
}
Truyền tham số cho Thread
– Chỉ chấp nhận tham số kiểu object
class DemoThread2
{
public void Demo()
{
Thread thread = new Thread(Print);
thread.Start(“Long đẹp choai”);
Console.ReadLine();
}
public void Print(object s)
{
Console.WriteLine(s);
}
}
Property ThreadState và ThreadPriority
ThreadState:
– Abort: Hủy thread.
– Suspend: Dừng thread tới khi được gọi lại hàm resume().
– Unstarted: Đã khởi tạo nhưng chưa được gọi hàm start().
– Running: Đang chạy.
– Stopped: Thread đang dừng.
– …
Tham khảo: https://msdn.microsoft.com/en-us/library/system.threading.threadstate(v=vs.110).aspx
ThreadPriority:
– Thuộc tính này xác định mức độ ưu tiên mà thread sẽ được thực thi so với các thread khác. Mỗi thread khi được tạo ra mang giá trị priority là Normal. Các giá trị mà thuộc tính có thể có bao gồm: Lowest, BelowNormal, Normal, AboveNormal và Highest.
Các phương thức của thread:
- Abort(): khi phương thức này được gọi, hệ thống sẽ ném ra một ngoại lệ ThreadAbortException để kết thúc thread. Sau khi gọi phương thức này, thuộc tính ThreadState sẽ chuyển sang giá trị Stopped.
- Suspend(): phương thức này sẽ tạm dừng việc thực thi của Thread vô thời hạn cho đến khi nó được yêu cầu chạy tiếp tục với phương thức Resume(). Tuy nhiên hai phương thức này được gắn attribute Obsolete để khuyến cáo rằng bạn nên sử dụng những phương pháp khác để thay thế.
- Sleep(): để dừng thread hiện tại trong một khoảng thời gian tính bằng milisecond, khi đó thread sẽ chuyển sang trạng thái WaitSleepJoin. Chú ý rằng đây là một phương thức static và bạn không cần tạo đối tượng Thread khi gọi nó.
- Join(): đây là một phương thức hữu ích trong trường hợp bạn muốn thực hiện một tác vụ nào đó sau khi thread đã kết thúc. Phương thức này chỉ được dùng sau khi bạn đã chạy Thread. Các tác vụ nằm phía dưới lệnh gọi Join() của một Thread chỉ được thực thi sau khi Thread đó hoàn tất công việc của mình.
Ví dụ tầm ảnh hưởng của sleep()
class DemoThread3
{
public static int n = 100000;
public void Demo()
{
Thread thread = new Thread(MethodA);
thread.Start();
MethodB();
Console.ReadLine();
}
public void MethodA()
{
Thread.Sleep(2000);
for (int i = 0; i < n; i++)
Console.Write(“@”);
}
public void MethodB()
{
for (int i = 0; i < n; i++)
Console.Write(“|”);
}
}
Ví dụ tầm ảnh hưởng của join()
class DemoThread4
{
public static int n = 100000;
public void Demo()
{
Thread threadA = new Thread(MethodA);
Thread threadB = new Thread(MethodB);
Thread threadC = new Thread(MethodC);
threadA.Start();
threadB.Start();
threadB.Join();
threadC.Start();
Console.ReadLine();
}
public void MethodA()
{
for (int i = 0; i < n; i++)
Console.Write(“@”);
}
public void MethodB()
{
for (int i = 0; i < n; i++)
Console.Write(“|”);
}
public void MethodC()
{
for (int i = 0; i < n; i++)
Console.Write(“-“);
}
}
Foreground và Background Thread
- Ứng dụng phân biệt Thread theo hai loại: Foreground thread và Background thread. Các thread ban đầu được tạo ra đều là foreground. Ứng dụng sẽ vẫn tiếp tục chạy nếu như tất cả các foreground thread chưa chạy xong mặc dù bạn đã thực hiện lệnh tắt ứng dụng. Và nếu tất cả các foreground thread hoàn thành, ứng dụng sẽ tắt, đồng thời tất cả background thread cũng bị “khai tử” theo. => Chương trình tắt -> Backgroud quéo. Foreground chạy điên cuồng tới khi cạn kiệt sinh lực.
- Xét về độ ưu tiên, foreground và background không có sự khác biệt nào trừ phi bạn đặt lại giá trị này cho chúng. Để xác định một Thread là foreground hay background, bạn sử dụng thuộc tính IsBackground
Ví dụ:
class DemoThread5
{
public static int n = 100100;
public void Demo()
{
Thread thread = new Thread(() =>
{
for (int i = 0; i < n; i++)
{
Console.Write(“1”);
}
});
// t1.IsBackground = true;
thread.Start();
Console.WriteLine(“Thread aborted”);
}
}
Thread Pooling
- Thread Pooling là một kĩ thuật cho phép bạn sử dụng các thread hiệu quả hơn bằng cách quản lý và phân phối chúng hợp lý, tận dụng tối đa thời gian nhàn rỗi và tăng hiệu suất của chương trình. Thread pooling là một kĩ thuật được áp dụng phổ biến trong các ứng dụng về I/O bất đồng bộ tập tin và truyền tải dữ liệu trên mạng.
- Mỗi chương trình được cung cấp một Thread pool khi khởi tạo, vì thế bạn không cần tạo một thể hiện của thread pool để sử dụng. Một đặc điểm của Thread pool là các thread sẽ được đặt ở chế độ background (Background Thread). Các tác vụ khi được thêm vào Thread pool sẽ được thực thi khi có một thread đang ở trạng thái sẵn sàng. Sau khi kết thúc một tác vụ, thread sẽ chuyển về trạng thái sẵn sàng để chờ một công việc khác.
- Bạn có thể tưởng tượng thread pool giống như một hàng đợi hay phòng bán vé với mặc định là 25 người làm việc, khi một người hoàn tất công việc bán vé cho khách thì khách hàng tiếp theo sẽ đến bắt đầu một giao dịch mới.
- Để sử dụng thread pool, bạn chỉ sử dụng phương thức tĩnh QueueUserWorkItem() của lớp ThreadPool. Phương thức này nhận tham số là một phương thức callback hoặc delegate, có thể dùng overload thứ hai để truyền thêm tham số cho phương thức cần thực thi. Sau khi được truyền vào thread pool, tác vụ đó được đặt vào hàng đợi và sẵn sàng thực thi bất cứ lúc nào có thread ở trạng thái sẵn sàng.
- Bạn có thể thay đổi số thread lớn nhất mà thread pool tạo ra bằng cách sử dụng phương thức ThreadPool.SetMaxThreads(). Trong mỗi phiên bản .Net giá trị mặc định này không giống nhau, ví dụ phiên bản .Net 2.0 thì giá trị này là 25, trong .Net 3.5 là 250. Bạn có thể kiểm tra điều này bằng cách sử dụng phương thức ThreadPool.GetMaxThreads().
- class DemoThread6
- {
- public static int n = 10;
- public void Demo()
- {
- ThreadPool.QueueUserWorkItem(MethodA);
- ThreadPool.QueueUserWorkItem(MethodA, “Lần 2”);
- }
- public void MethodA(object s)
- {
- for (int i = 0; i < n; i++)
- {
- Console.WriteLine(s);
- Thread.Sleep(500);
- }
- }
- }
Đồng bộ hóa và locking
class DemoThread7
{
static int amount = 0;
public void Demo()
{
Thread t1 = new Thread(IncreaseAmount);
Thread t2 = new Thread(DecreaseAmount);
t1.Start();
t2.Start();
}
public void IncreaseAmount()
{
for (int i = 0; i < 100; i++)
{
amount++;
if (amount > 0)
{
Thread.Sleep(1);
Console.Write(amount + “\t”);
}
}
}
public void DecreaseAmount()
{
for (int i = 0; i < 100; i++)
{
amount–;
}
}
}
Deadlock
- Đồng bộ hóa khi sử dụng thread là một công việc cần thiết, tuy nhiên nếu không cẩn thận bạn sẽ gặp phải tình trạng chương trình dừng hoạt động vô thời hạn. Tình trạng này được đặt tên là deadlock. Deadlock xảy ra khi có ít nhất hai thread cùng đợi thread kia giải phóng, thật “trùng hợp” là cả hai lại đang giữ “chìa khóa” của nhau.
- Để dễ hiểu bạn hãy tưởng tượng có hai người hàng xóm bị nhốt trong hai căn phòng của chính mình và người này lại giữ chìa khóa của người kia. Và người này sẽ không thể đưa chìa khóa cho người kia nếu như không ra khỏi phòng. Rốt cuộc cả hai sẽ bị nhốt trong phòng mãi mãi?
Chia sẻ:
- X
Từ khóa » Thread Trong C# Là Gì
-
C# – Cơ Bản Về Thread | YinYang's Programing Blog
-
Thread Và Tasks Trong C# Sử Dụng Như Thế Nào? - CodeLearn
-
Multi Threading (đa Luồng) Trong C# | How Kteam
-
Đa Luồng (Multithread) Trong C# - Học Lập Trình C# Online - VietTuts
-
Hướng Dẫn Lập Trình đa Luồng Trong C# - Openplanning
-
Tìm Hiểu C# Và ứng Dụng: Thread Và Sự đồng Bộ
-
Lập Trình Multi Thread C# Sử Dụng Parallel Chạy Song Song Các Tác Vụ
-
Luồng Thực Thi (thread), Lập Trình đa Luồng (multithreading) | Tự Học ICT
-
Chi Tiết Blog Multithreading Trong Lập Trình - Vimentor
-
Thread Và Tasks Trong C# Sử Dụng Như Thế Nào? - Chickgolden
-
Thread In C# Đa Luồng Trong C# Thread.Sleep Thread.Join Thread ...
-
Lập Trình Bất đồng Bộ Trong C# - Viblo
-
Lock Statement - C# Reference | Microsoft Docs
-
Đa Luồng (Multithread) Trong C# - Vay Tiền Online Bằng CMND