Tiến trình(Process) và Tiểu trình (Thread) trong C#


Tiến trình và tiểu trình




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.





Thread hay còn gọi là tiểu trình là khái niệm khá quen thuộc trong lập 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. Trong bài này, bạn sẽ được giới thiệu cơ bản về cách làm việc với thread cũng như kĩ thuật đồng bộ hóa và hiện tượng deadlock.

Tạo và chạy thread:

.Net cung cấp lớp Thread trong namespace System.Threading cùng với những phương thức cần thiết để giúp lập trình viên sử dụng một cách đơn giản và hiệu quả. Để tạo một thread mới bạn làm theo các bước sau:
–          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 method hoặ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.


using System; using System.Threading; namespace TLSDataSlot { class Program { static void Main() { Thread[] newThreads = new Thread[4]; for (int i = 0; i < newThreads.Length; i++) { newThreads[i] = new Thread(new ThreadStart(Slot.SlotTest)); newThreads[i].Start(); } } } class Slot { static Random randomGenerator = new Random(); public static void SlotTest() { // Set different data in each thread's data slot. Thread.SetData( Thread.GetNamedDataSlot("Random"), randomGenerator.Next(1, 200)); // Write the data from each thread's data slot. Console.WriteLine("Data in thread_{0}'s data slot: {1,3}", AppDomain.GetCurrentThreadId().ToString(), Thread.GetData( Thread.GetNamedDataSlot("Random")).ToString()); // Allow other threads time to execute SetData to show // that a thread's data slot is unique to the thread. Thread.Sleep(1000); Console.WriteLine("Data in thread_{0}'s data slot is still: {1,3}", AppDomain.GetCurrentThreadId().ToString(), Thread.GetData( Thread.GetNamedDataSlot("Random")).ToString()); // Allow time for other threads to show their data, // then demonstrate that any code a thread executes // has access to the thread's named data slot. Thread.Sleep(1000); Other o = new Other(); o.ShowSlotData(); Console.ReadLine(); } } public class Other { public void ShowSlotData() { // This method has no access to the data in the Slot // class, but when executed by a thread it can obtain // the thread's data from a named slot. Console.WriteLine( "Other code displays data in thread_{0}'s data slot: {1,3}", AppDomain.GetCurrentThreadId().ToString(), Thread.GetData( Thread.GetNamedDataSlot("Random")).ToString()); } } }
using System; using System.Threading; namespace ThreadStatic { class Program { static void Main(string[] args) { for (int i = 0; i < 3; i++) { Thread newThread = new Thread(ThreadData.ThreadStaticDemo); newThread.Start(); } } } class ThreadData { [ThreadStaticAttribute] static int threadSpecificData; public static void ThreadStaticDemo() { // Store the managed thread id for each thread in the static // variable. threadSpecificData = Thread.CurrentThread.ManagedThreadId; // Allow other threads time to execute the same code, to show // that the static data is unique to each thread. Thread.Sleep(1000); // Display the static data. Console.WriteLine("Data for managed thread {0}: {1}", Thread.CurrentThread.ManagedThreadId, threadSpecificData); } } }

Truyền tham số cho thread

Thread(ThreadStart) Thread(ParameterizedThreadStart) No Parameters Hide Copy Code Thread workerThread = new Thread(StartThread); Console.WriteLine("Main Thread Id {0}", Thread.CurrentThread.ManagedThreadId.ToString()); workerThread.Start(); .... ....
public static void StartThread() { for (int i = 0; i < 10; i++) { Console.WriteLine("Thread value {0} running on Thread Id {1}", i.ToString(), Thread.CurrentThread.ManagedThreadId.ToString()); } } Single Parameter Hide Copy Code //using parameter Thread workerThread2 = new Thread(ParameterizedStartThread); // the answer to life the universe and everything, 42 obviously workerThread2.Start(42); Console.ReadLine(); .... ....
public static void ParameterizedStartThread(object value) { Console.WriteLine("Thread passed value {0} running on Thread Id {1}", value.ToString(), Thread.CurrentThread.ManagedThreadId.ToString()); }

CallBack

using System; using System.Threading; namespace CallBacks { class Program { private string message; private static Timer timer; private static bool complete; static void Main(string[] args) { Program p = new Program(); Thread workerThread = new Thread(p.DoSomeWork); workerThread.Start(); //create timer with callback TimerCallback timerCallBack = new TimerCallback(p.GetState); timer = new Timer(timerCallBack, null, TimeSpan.Zero, TimeSpan.FromSeconds(2)); //wait for worker to complete do { //simply wait, do nothing } while (!complete); Console.WriteLine("exiting main thread"); Console.ReadLine(); } public void GetState(Object state) { //not done so return if (message == string.Empty) return; Console.WriteLine("Worker is {0}", message); //is other thread completed yet, if so signal main //thread to stop waiting if (message == "Completed") { timer.Dispose(); complete = true; } } public void DoSomeWork() { message = "processing"; //simulate doing some work Thread.Sleep(3000); message = "Completed"; } } }


Ntech Developers

Programs must be written for people to read, and only incidentally for machines to execute.

Post a Comment

Previous Post Next Post