nguyenthuctuan

New Member

Download miễn phí Đề tài Giới thiệu ngôn ngữ lập trình C#





Hệ điều hành Windows hỗ trợ một khái niệm gọi là timeslicing cho phép nhiều luồng cùng mức ưu tiên cùng chia sẻ một vi xử lư. Không có timeslicing, mỗi luồng có mức ưu tiên ngang nhau sẽ sử dụng processor cho đến khi hoàn thành rồi các luồng khác mới có CPU để thực hiện. Với timeslicing, mỗi luồng nhận được một khoảng thời gian ngắn nhất định của bộ vi xử lư được gọi là thời luợng (quantum) xuyên suốt quá tŕnh thực hiện luồng. Tại một thời lượng hoàn thành, thậm chí nếu luồng chưa hoàn thành th́ processor sẽ vẫn lấy luồng trong hàng đợi của các luồng đồng ưu tiên vào thực hiện, nếu như có luồng chờ đợi.
 



Để tải bản Đầy Đủ của tài liệu, xin Trả lời bài viết này, Mods sẽ gửi Link download cho bạn sớm nhất qua hòm tin nhắn.
Ai cần download tài liệu gì mà không tìm thấy ở đây, thì đăng yêu cầu down tại đây nhé:
Nhận download tài liệu miễn phí

Tóm tắt nội dung tài liệu:

g thức ( ở vi dụ này MyThread ) tham chiếu bởi thay mặt chuyển giao Delegate. Khi cách Start được gọi thì nó có thể gây ra một số ngoại lệ mà ta cần chú ý :
ThreadStateException
Luông đã bắt rồi.
SecurityException
Lời gọi không có cho phép thực hiện
OutOfMemoryException
Không đủ bộ nhớ thực hiện luồng
NullReferenceException
Lời gọi tham chiếu một luồng mà null
ở đây ta cũng chú ý là một khi luồng đã ngắt thì không thể có lời gọi Start lần nữa. Khi phưong thức Start khởi đầu luồng này, cách Start sẽ trả điều khiển cho luồng gọi ngay lập tức. Khi đó luồng gọi sẽ thi hành đồng thời luồng vừa phát động.
Để biết được trạng thái của một luồng ta có thể sử dụng thuộc tính
Thread.ThreadSate hay thuộc tính Thread.isAlive
[C#]
public ThreadState ThreadState {get;} (**)
[C#]
public bool IsAlive {get;}) (*)
(*) - Thuộc tính này có giá trị là true khi mà luồng đã được gọi và chưa chết ( tức là cách stop của nó chưa được gọi và cách kiểm soát run của nó chưa hoàn tất nhiệm vụ) ngược lại nó có giá trị false khi luồng đã kết thúc .
(**)- Giá trị của thuộc tính này trả về là trạng thái hiện hành của luồn và khởi đầu với giá trị unstarted.
Khi tạo một luồng ta có thể gán tên cho luồng đó để nhấn dạng tên luồng đang chạy bằng cách sử dụng thuộc tính Thread.Name để gán thuộc tên cho luồng. Điều cần lưu ý khi sử dụng thuộc tính này là đây là thuộc tính chỉ ghi và một luồng chỉ được dặt tên cho một lần duy nhất mà thôi nếu không sẽ gây ra một lỗi ngoại lệ InvalidOperationException (thiết đặt một yêu cầu mà tên đó đã được đặt rồi).
II.2.2. Nhập luồng ( join thread )
Khi ta cần dừng xử lý một luồng và chờ đợi cho luồng thứ hai kết thúc gọi là luồng thứ nhất gia nhập luồng thứ hai hay nói cách khác là gắn đầu luồng một vào đuôi luồng thứ hai. C# cung cấp cho chúng ta ba cách :
public void Join() ;(*)
public bool Join(int);(**)
public bool Join(TimeSpan);(***)
(*) Khi dùng cách này thì nó sẽ đóng luồng cho đến khi luồng thứ hai bị ngắt. Tuy nhiên sự chờ đợi không hạn định này có thể gây ra vấn đề nghiêm trọng đó là bế tắc hoàn toàn (deadlock) và trì hoãn vô hạn (infinitive postponement). cách này tung ra hai lỗi ngoại lệ là ThreadSateException khi mà lời gọi cố gắng gia nhập luồng trong khi đang ở trạng thai ThreadState.Unstarted và ngoại lệ thứ hai xảy ra là ThreadInterruptException tức là luồng bị ngắt trong khi đang chờ đợi.
(**) Khi dùng cách này thì luồng sẽ bị đóng cho đến khi luồng thứ hai ngắt hay thời gian chỉ định hết. cách này trả lại giá trị true nếu luồng hai kết thúc hay trả lại false khi hết thời gian mà luồng hai chưa kết thúc. cách này cũng sinh ra hai ngoai lệ là ThreadSateException tức luồng chưa bắt đầu hay do thời gian là âm ArgumentOutOfRangeException.
Khi thực hiện các cách này thì chúng đều làm thay đổi trạng thái của luồng gọi tới ThreadState.WaitSleepJoin và ta cần chú ý là không gọi cách này khi luồng đang ở trạng thái ThreadState.Unstarted.
Ví dụ:
using System;
using System.Thread;
class test
{ public static void thuyet() {
Console.WriteLine(“Trangthai:”+Second.CurrentState.ThreadSate);
/*sử dụng thuộc tính CurrentThread để trả về trạng thái của luồng của luồng
hiện thời */
}
public static void Main()
{
Console.WriteLine(“Luong chinh”);
ThreadStart my=new ThreadStart(thuyet);
Thread second=new Thread(my);
second.Start();
second.Join();
Console.WriteLine(“Ket thuc:”+second.ThreadState);
}
}
Trong chương trình trên khi thực hiện nếu ta bỏ đi dòng lệnh second.Join() thì chương trình cho ta đầu ra :
Luong chinh.
Ketthuc:unstarted
Trangthai:Running.
Tuy nhiên khi ta cho dòng lệnh vào thì khi đó luồng chương trình chính sẽ đi vào trạng thái Thread.WaitSleepJoin và chờ cho luồng vừa tạo ra kết thúc mới tiếp tục làm tiếp do đó đầu ra của chương trình trên:
Luong chinh.
Trangthai:Running
Ketthuc:unstarted
II.2.3. Dừng một luồng
Để dùng một luồng trong C# ta có thể sử dụng cách
Thread.Susppend [ public void suspend();]
Tuy nhiên khi ta gọi cách này, hệ thống không thực hiện ngay hành động này ngay lập tức. Thay vào đó, nó ghi nhận một luồng đình chỉ vừa yêu cầu và chờ đợi cho đến khi luồng đạt đến một điểm an toàn (safe point) trước khi thực sự đình chỉ luồng đó hoạt động. Một điểm an toàn cho một luồng là một điểm an toàn cho gom rác. cách này chỉ sẽ không hiệu quả khi chúng ta gọi cách này khi mà luồng đã bị dừng và để khôi phục luồng bị đình chỉ ta sử dụng cách Thread.Resume() để khôi phục lại hoạt động của luồng.
Lớp Thread còn đưa ra cho ta một cách Thread.Sleep cũng dùng cho mục đích như trên. cách này lấy tham số là thời gian chỉ định luồng sẽ dừng trong bao lâu sau đó khôi phục thực hiện. Đây không phải là sự định thời khóa biểu cho luồng thực hiện và khi thực hiện thì cách này đưa luồng vào trạng thái WaitSleepJoin. Để gọi một luồng ra khỏi trạng thái WaitSleepJoin chúng ta có thể sử dụng cách Thread.Interrupt() để làm luồng trở lại hoạt động.
II.2.4. Hủy một luồng
cách Thread .Abort để làm ngưng hẳn một luồng đang hoạt động, có hai cách cho hoạt động này: một là không đối số hai là có đối số tuy nhiên chúng ta thường sử dụng cách không đối số là chủ yếu:
public void Abort();
public void Abort(Object);
Khi gọi cách này đưa ra một ngoại lệ ThreadAbortException trong luồng để bắt đầu hủy luồng. Đây là một ngoại lệ đặc biệt có thể đón bắt bàng đoạn mã của ứng dụng, tuy nhiên cuối của đoạn mã nếu ta đưa ra một cách ResetAbort() thì Abort() sẽ bị bỏ qua và ngăn chặn ThreadAbortException dừng luồng hiện hành.
Trên đây là những cách chủ yếu của lớp Thread mà chúng ta thường hay sử dụng trong việc thao tác và xử lý với luồng .Còn những cách khác quan trọng khác nữa sẽ khảo sát trong các phần tiếp theo.
II.3. Vòng đời của một luồng
Trong phần này chúng ta sẽ tìm hiểu các trạng thái và sự chuyển đổi giữa các trạng thái của luồng và hai lớp ảnh hưởng đến các ứng dụng đa luồng ở đây là lớp Thread và Monitor.
Khi một luồng mới tạo thành nó ở trạng thái unstarted, luồng duy trì ở trạng thái này cho đến khi cách Thread.Start() đặt luồng vào trạng thái bắt đầu chạy Started và lập tức chuyển điều khiển đến luồng vừa gọi. Luồng với mức độ ưu tiên cao nhất sẽ bắt đầu với trạng thái Running khi hệ điều hành gán CPU cho ứng dụng.
Luồng sẽ đi vào trạng thái chết khi thay mặt chuyển giao của nó bị ngắt. Một chương trình có thể buộc một luồng phải dừng bằng Thread.Abort() trên một đối tượng Thread thích hợp. cách này đưa ra một ngoại lệ ThreadAbortException trong luồng. Khi luồng ở trong trạng thái stopped thì không có tham chiếu tới đối tượng luồng do đó bộ thu gom rác tự dộng sẽ dỡ bỏ đối tượng luồng ra khỏi bộ nhớ.
Có ba phương cách để cho một luồng đang Running vào trạng thái WaitSleepJoin. Một luồng có thể gọi cách Monitor.Wait() để vào trạng thái WaitSleepJoin và một luồng khi ở trạng thái này nó chỉ trở lại trạng thái Running khi ...
 

Kiến thức bôn ba

Các chủ đề có liên quan khác

Top