Tiểu trình, tiến trình , và sự đồng bộ phần 4
Số trang: 10
Loại file: pdf
Dung lượng: 194.62 KB
Lượt xem: 11
Lượt tải: 0
Xem trước 2 trang đầu tiên của tài liệu này:
Thông tin tài liệu:
Bạn muốn biết khi nào một tiểu trình đã kết thúc. Sử dụng thuộc tính IsAlive hay phương thức Join của lớp Thread. Cách dễ nhất để kiểm tra một tiểu trình đã kết thúc hay chưa là kiểm tra thuộc tính Thread.IsAlive.
Nội dung trích xuất từ tài liệu:
Tiểu trình, tiến trình , và sự đồng bộ phần 4 1.1 Nhận biết khi nào một tiểu trình kết thúc Bạn muốn biết khi nào một tiểu trình đã kết thúc. Sử dụng thuộc tính IsAlive hay phương thức Join của lớp Thread.Cách dễ nhất để kiểm tra một tiểu trình đã kết thúc hay chưa là kiểm tra thuộc tínhThread.IsAlive. Thuộc tính này trả về true nếu tiểu trình đã được khởi chạy nhưng chưakết thúc hay bị hủy.Thông thường, bạn sẽ cần một tiểu trình để đợi một tiểu trình khác hoàn tất việc xử lý củanó. Thay vì kiểm tra thuộc tính IsAlive trong một vòng lặp, bạn có thể sử dụng phươngthức Thread.Join. Phương thức này khiến tiểu trình đang gọi dừng lại (block) cho đến khitiểu trình được tham chiếu kết thúc. Bạn có thể tùy chọn chỉ định một khoảng thời gian(giá trị int hay TimeSpan) mà sau khoảng thời gian này, Join sẽ hết hiệu lực và quá trìnhthực thi của tiểu trình đang gọi sẽ phục hồi lại. Nếu bạn chỉ định một giá trị time-out, Jointrả về true nếu tiểu trình đã kết thúc, và false nếu Join đã hết hiệu lực.Ví dụ dưới đây thực thi một tiểu trình thứ hai và rồi gọi Join để đợi tiểu trình thứ hai kếtthúc. Vì tiểu trình thứ hai mất 5 giây để thực thi, nhưng phương thức Join chỉ định giá trịtime-out là 3 giây, nên Join sẽ luôn hết hiệu lực và ví dụ này sẽ hiển thị một thông báo racửa sổ Console.using System;using System.Threading;public class ThreadFinishExample { private static void DisplayMessage() { // Hiển thị một thông báo ra cửa sổ Console 5 lần. for (int count = 0; count < 5; count++) { Console.WriteLine({0} : Second thread, DateTime.Now.ToString(HH:mm:ss.ffff)); // Nghỉ 1 giây. Thread.Sleep(1000); } } public static void Main() { // Tạo một thể hiện ủy nhiệm ThreadStart // tham chiếu đến DisplayMessage. ThreadStart method = new ThreadStart(DisplayMessage); // Tạo một đối tượng Thread và truyền thể hiện ủy nhiệm // ThreadStart cho phương thức khởi dựng của nó. Thread thread = new Thread(method); Console.WriteLine({0} : Starting second thread., DateTime.Now.ToString(HH:mm:ss.ffff)); // Khởi chạy tiểu trình thứ hai. thread.Start(); // Dừng cho đến khi tiểu trình thứ hai kết thúc, // hoặc Join hết hiệu lực sau 3 giây. if (!thread.Join(3000)) { Console.WriteLine({0} : Join timed out !!, DateTime.Now.ToString(HH:mm:ss.ffff)); } // Nhấn Enter để kết thúc. Console.WriteLine(Main method complete. Press Enter.); Console.ReadLine(); }} 1.2 Đồng bộ hóa quá trình thực thi của nhiều tiểu trình Bạn cần phối hợp các hoạt động của nhiều tiểu trình để bảo đảm sử dụng hiệu quả các tài nguyên dùng chung, và bạn không làm sai lạc dữ liệu dùng chung khi một phép chuyển ngữ cảnh tiểu trình (thread context switch) xảy ra trong quá trình thay đổi dữ liệu. Sử dụng các lớp Monitor, AutoResetEvent, ManualResetEvent, và Mutex (thuộc không gian tên System.Threading).Thách thức lớn nhất trong việc viết một ứng dụng hỗ-trợ-đa-tiểu-trình là bảo đảm các tiểutrình làm việc trong sự hòa hợp. Việc này thường được gọi là “đồng bộ hóa tiểu trình” vàbao gồm: • Bảo đảm các tiểu trình truy xuất các đối tượng và dữ liệu dùng chung một cách phù hợp để không gây ra sai lạc. • Bảo đảm các tiểu trình chỉ thực thi khi thật sự cần thiết và phải đảm bảo rằng chúng chỉ được thực thi với chi phí tối thiểu khi chúng rỗi.Cơ chế đồng bộ hóa thông dụng nhất là lớp Monitor. Lớp này cho phép một tiểu trìnhđơn thu lấy chốt (lock) trên một đối tượng bằng cách gọi phương thức tĩnh Monitor.Enter.Bằng cách thu lấy chốt trước khi truy xuất một tài nguyên hay dữ liệu dùng chung, tachắc chắn rằng chỉ có một tiểu trình có thể truy xuất tài nguyên đó cùng lúc. Một khi đãhoàn tất với tài nguyên, tiểu trình này sẽ giải phóng chốt để tiểu trình khác có thể truyxuất nó. Khối mã thực hiện công việc này thường được gọi là vùng hành căng (criticalsection).Bạn có thể sử dụng bất kỳ đối tượng nào đóng vai trò làm chốt, và sử dụng từ khóa thisđể thu lấy chốt trên đối tượng hiện tại. Điểm chính là tất cả các tiểu trình khi truy xuấtmột tài nguyên dùng chung phải thu lấy cùng một chốt. Các tiểu trình khác khi thu lấychốt trên cùng một đối tượng sẽ block (đi vào trạng thái WaitSleepJoin) và được thêmvào hàng sẵn sàng (ready queue) của chốt này cho đến khi tiểu trình chủ giải phóng nóbằng phương thức tĩnh Monitor.Exit. Khi tiểu trình chủ gọi Exit, một trong các tiểu trìnhtừ hàng sẵn sàng sẽ thu lấy chốt. Nếu tiểu trình chủ không giải phóng chốt bằng Exit, tấtcả các tiểu trình khác sẽ block vô hạn định. Vì vậy, cần đặt lời gọi Exit bên trong khốifinally để bảo đảm nó được gọi cả khi ngoại lệ xảy ra.Vì Monitor thường xuyên được sử dụng trong các ứng dụng hỗ-trợ-đa-tiểu-trình nên C#cung cấp hỗ trợ mức-ngôn-ngữ thông qua lệnh lock. Khối mã được gói trong lệnh locktương đương với gọi Monitor.Enter khi đi vào khối mã này, và gọi Monitor.Exit khi đi rakhối mã này. Ngoài ra, trình biên dịch tự động đặt lời gọi Monitor.Exit trong khối finallyđể bảo đảm chốt được giải phóng khi một ngoại lệ bị ném.Tiểu trình chủ (sở hữu chốt) có thể gọi Monitor.Wait để giải phóng chốt và đặt tiểu trìnhnày vào hàng chờ (wait queue). Các tiểu trình trong hàng chờ cũng có trạng thái làWaitSleepJoin và sẽ tiếp tục block cho đến khi tiểu trình chủ gọi phương thức Pulse hayPulseAll của lớp Monitor. Phương thức Pulse di chuyển một trong các tiểu trình từ hàngchờ vào hàng sẵn sàng, còn phương thức PulseAll thì di chuyển tất cả các tiểu trình. Khimột tiểu trình đã được di chuyển từ hàng chờ vào hàng sẵn sàng, nó có thể thu lấy chốttrong lần giải phóng kế tiếp. Cần hiểu rằng các tiểu trình thuộc hàng chờ sẽ không thuđược chốt, chúng sẽ đợi vô hạ ...
Nội dung trích xuất từ tài liệu:
Tiểu trình, tiến trình , và sự đồng bộ phần 4 1.1 Nhận biết khi nào một tiểu trình kết thúc Bạn muốn biết khi nào một tiểu trình đã kết thúc. Sử dụng thuộc tính IsAlive hay phương thức Join của lớp Thread.Cách dễ nhất để kiểm tra một tiểu trình đã kết thúc hay chưa là kiểm tra thuộc tínhThread.IsAlive. Thuộc tính này trả về true nếu tiểu trình đã được khởi chạy nhưng chưakết thúc hay bị hủy.Thông thường, bạn sẽ cần một tiểu trình để đợi một tiểu trình khác hoàn tất việc xử lý củanó. Thay vì kiểm tra thuộc tính IsAlive trong một vòng lặp, bạn có thể sử dụng phươngthức Thread.Join. Phương thức này khiến tiểu trình đang gọi dừng lại (block) cho đến khitiểu trình được tham chiếu kết thúc. Bạn có thể tùy chọn chỉ định một khoảng thời gian(giá trị int hay TimeSpan) mà sau khoảng thời gian này, Join sẽ hết hiệu lực và quá trìnhthực thi của tiểu trình đang gọi sẽ phục hồi lại. Nếu bạn chỉ định một giá trị time-out, Jointrả về true nếu tiểu trình đã kết thúc, và false nếu Join đã hết hiệu lực.Ví dụ dưới đây thực thi một tiểu trình thứ hai và rồi gọi Join để đợi tiểu trình thứ hai kếtthúc. Vì tiểu trình thứ hai mất 5 giây để thực thi, nhưng phương thức Join chỉ định giá trịtime-out là 3 giây, nên Join sẽ luôn hết hiệu lực và ví dụ này sẽ hiển thị một thông báo racửa sổ Console.using System;using System.Threading;public class ThreadFinishExample { private static void DisplayMessage() { // Hiển thị một thông báo ra cửa sổ Console 5 lần. for (int count = 0; count < 5; count++) { Console.WriteLine({0} : Second thread, DateTime.Now.ToString(HH:mm:ss.ffff)); // Nghỉ 1 giây. Thread.Sleep(1000); } } public static void Main() { // Tạo một thể hiện ủy nhiệm ThreadStart // tham chiếu đến DisplayMessage. ThreadStart method = new ThreadStart(DisplayMessage); // Tạo một đối tượng Thread và truyền thể hiện ủy nhiệm // ThreadStart cho phương thức khởi dựng của nó. Thread thread = new Thread(method); Console.WriteLine({0} : Starting second thread., DateTime.Now.ToString(HH:mm:ss.ffff)); // Khởi chạy tiểu trình thứ hai. thread.Start(); // Dừng cho đến khi tiểu trình thứ hai kết thúc, // hoặc Join hết hiệu lực sau 3 giây. if (!thread.Join(3000)) { Console.WriteLine({0} : Join timed out !!, DateTime.Now.ToString(HH:mm:ss.ffff)); } // Nhấn Enter để kết thúc. Console.WriteLine(Main method complete. Press Enter.); Console.ReadLine(); }} 1.2 Đồng bộ hóa quá trình thực thi của nhiều tiểu trình Bạn cần phối hợp các hoạt động của nhiều tiểu trình để bảo đảm sử dụng hiệu quả các tài nguyên dùng chung, và bạn không làm sai lạc dữ liệu dùng chung khi một phép chuyển ngữ cảnh tiểu trình (thread context switch) xảy ra trong quá trình thay đổi dữ liệu. Sử dụng các lớp Monitor, AutoResetEvent, ManualResetEvent, và Mutex (thuộc không gian tên System.Threading).Thách thức lớn nhất trong việc viết một ứng dụng hỗ-trợ-đa-tiểu-trình là bảo đảm các tiểutrình làm việc trong sự hòa hợp. Việc này thường được gọi là “đồng bộ hóa tiểu trình” vàbao gồm: • Bảo đảm các tiểu trình truy xuất các đối tượng và dữ liệu dùng chung một cách phù hợp để không gây ra sai lạc. • Bảo đảm các tiểu trình chỉ thực thi khi thật sự cần thiết và phải đảm bảo rằng chúng chỉ được thực thi với chi phí tối thiểu khi chúng rỗi.Cơ chế đồng bộ hóa thông dụng nhất là lớp Monitor. Lớp này cho phép một tiểu trìnhđơn thu lấy chốt (lock) trên một đối tượng bằng cách gọi phương thức tĩnh Monitor.Enter.Bằng cách thu lấy chốt trước khi truy xuất một tài nguyên hay dữ liệu dùng chung, tachắc chắn rằng chỉ có một tiểu trình có thể truy xuất tài nguyên đó cùng lúc. Một khi đãhoàn tất với tài nguyên, tiểu trình này sẽ giải phóng chốt để tiểu trình khác có thể truyxuất nó. Khối mã thực hiện công việc này thường được gọi là vùng hành căng (criticalsection).Bạn có thể sử dụng bất kỳ đối tượng nào đóng vai trò làm chốt, và sử dụng từ khóa thisđể thu lấy chốt trên đối tượng hiện tại. Điểm chính là tất cả các tiểu trình khi truy xuấtmột tài nguyên dùng chung phải thu lấy cùng một chốt. Các tiểu trình khác khi thu lấychốt trên cùng một đối tượng sẽ block (đi vào trạng thái WaitSleepJoin) và được thêmvào hàng sẵn sàng (ready queue) của chốt này cho đến khi tiểu trình chủ giải phóng nóbằng phương thức tĩnh Monitor.Exit. Khi tiểu trình chủ gọi Exit, một trong các tiểu trìnhtừ hàng sẵn sàng sẽ thu lấy chốt. Nếu tiểu trình chủ không giải phóng chốt bằng Exit, tấtcả các tiểu trình khác sẽ block vô hạn định. Vì vậy, cần đặt lời gọi Exit bên trong khốifinally để bảo đảm nó được gọi cả khi ngoại lệ xảy ra.Vì Monitor thường xuyên được sử dụng trong các ứng dụng hỗ-trợ-đa-tiểu-trình nên C#cung cấp hỗ trợ mức-ngôn-ngữ thông qua lệnh lock. Khối mã được gói trong lệnh locktương đương với gọi Monitor.Enter khi đi vào khối mã này, và gọi Monitor.Exit khi đi rakhối mã này. Ngoài ra, trình biên dịch tự động đặt lời gọi Monitor.Exit trong khối finallyđể bảo đảm chốt được giải phóng khi một ngoại lệ bị ném.Tiểu trình chủ (sở hữu chốt) có thể gọi Monitor.Wait để giải phóng chốt và đặt tiểu trìnhnày vào hàng chờ (wait queue). Các tiểu trình trong hàng chờ cũng có trạng thái làWaitSleepJoin và sẽ tiếp tục block cho đến khi tiểu trình chủ gọi phương thức Pulse hayPulseAll của lớp Monitor. Phương thức Pulse di chuyển một trong các tiểu trình từ hàngchờ vào hàng sẵn sàng, còn phương thức PulseAll thì di chuyển tất cả các tiểu trình. Khimột tiểu trình đã được di chuyển từ hàng chờ vào hàng sẵn sàng, nó có thể thu lấy chốttrong lần giải phóng kế tiếp. Cần hiểu rằng các tiểu trình thuộc hàng chờ sẽ không thuđược chốt, chúng sẽ đợi vô hạ ...
Tìm kiếm theo từ khóa liên quan:
công nghệ thông tin kĩ thuật lập trình ngôn ngữ lập trình ngôn ngữ C# C# Tiểu trình tiến trình và sự đồng bộ phần 4Tài liệu có liên quan:
-
52 trang 468 1 0
-
Top 10 mẹo 'đơn giản nhưng hữu ích' trong nhiếp ảnh
11 trang 367 0 0 -
96 trang 334 0 0
-
74 trang 329 0 0
-
Đồ án tốt nghiệp: Xây dựng ứng dụng di động android quản lý khách hàng cắt tóc
81 trang 321 0 0 -
Tài liệu dạy học môn Tin học trong chương trình đào tạo trình độ cao đẳng
348 trang 320 1 0 -
Giáo trình Lập trình hướng đối tượng: Phần 2
154 trang 316 0 0 -
Kỹ thuật lập trình trên Visual Basic 2005
148 trang 310 0 0 -
Báo cáo thực tập thực tế: Nghiên cứu và xây dựng website bằng Wordpress
24 trang 304 0 0 -
Tài liệu hướng dẫn sử dụng thư điện tử tài nguyên và môi trường
72 trang 302 0 0