Chương 8 ĐA TIẾN TRÌNH 1 NỘI DUNG CHÍNH 1 Giới thiệu tiến trình 2 Đa tiến trình trên .NET 3 Quản lý tiến trình 4 Đồng bộ hóa 2 NỘI DUNG CHÍNH 1 Giới thiệu tiến trình 2 Đa tiến trình trên .NET 3 Quản lý tiến trình 4 Đồng bộ hóa 3 Tiến trình • Tiến trình (thread) thường được tạo ra khi muốn làm đồng thời 2 việc trong cùng một thời điểm 4 Giới thiệu đa tiến trình • Một bộ xử lý chỉ có thể làm một việc vào một thời điểm • Nếu có một hệ thống đa xử lý, theo lý thuyết có thể có nhiều lệnh được thi hành đồng bộ, mỗi lệnh trên một bộ xử lý. • Tuy nhiên ta chỉ làm việc trên một bộ xử lý. • Do đó các công việc không thể xảy ra cùng lúc. • Thực sự thì hệ điều hành window làm điều này bằng một thủ tục gọi là pre emptive multitasking 5 Giới thiệu đa tiến trình • Window lấy 1 luồng vào trong vài tiến trình và cho phép luồng đó chạy 1 khoảng thời gian ngắn (gọi là time slice).
Khi thời gian này kết thúc, Window lấy quyền điều khiển lại và lấy 1 luồng khác và lại cấp 1 khoảng thời gian time slice. Vì khoảng thời gian này quá ngắn nên ta có cảm tưởng như mọi thứ đều xảy ra cùng lúc. • Khi có nhiều cửa sổ trên màn hình, mỗi cửa sổ đại diện cho một tiến trình khác nhau. Người dùng vẫn có thể tương tác với bất kì cửa sổ nào và được đáp ứng ngay lập tức.
Nhưng thực sự việc đáp ứng này xảy ra vào sau khoảng thời gian time slice của luồng đương thời. 6 Ứng dụng trên Windows • Đa tiến trình có nhiều lợi ích trong các ứng dụng windows như: – Mỗi cửa sổ con trong một ứng dụng MDI có thể được gán cho một tiểu trình khác nhau. – Nếu phần đồ họa của chương trình mất nhiều thời gian để thực thi, GUI sẽ được khóa cho đến khi hoàn tất việc vẽ lại. Tuy nhiên, có thể chỉ định một tiểu trình riêng cho hàm OnDraw, như vậy làm cho ứng dụng được phản hồi khi xảy ra tình trạng vẽ quá lâu.
– Nhiều tiểu trình có thể thực thi đồng thời nếu có nhiều CPU trong hệ thống do đó tăng tốc độ thực hiện của chương trình. – Sự mô phỏng phức tạp có thể được thực hiện hiệu quả bằng việc gán một tiểu trình riêng cho mỗi thực thể mô phỏng. – Các sự kiện quan trọng có thể được điều khiển hiệu quả thông qua việc phân cho một tiểu trình có độ ưu tiên cao. 7 Các trạng thái tiến trình: Chu trình của một tiến trình • Trạng thái tiến trình: – Chưa bắt đầu (Unstarted): • Khi một tiến trình được khởi tạo • Tiếp tục cho đến khi phương thức Start của tiến trình được gọi – Bắt đầu (Started): • Duy trì tới lúc bộ xử lý bắt đầu thực hiện nó – Đang thực thi (Running): • Tiến trình bắt đầu có độ ưu tiên cao nhất sẽ vào trạng thái thực thi đầu tiên • Bắt đầu thực thi khi bộ xử lý được gán cho tiến trình • ThreadStart Tiến trình bắt đầu ủy nhiệm các hành động cụ thể cho các tiến trình – Ngừng (Stopped): • Khi ủy nhiệm kết thúc • Nếu chương trình gọi phương thức Abort của tiến trình 8 Các trạng thái tiến trình: Chu trình của một tiến trình • Trạng thái tiến trình: – Blocked: • Blocked khi yêu cầu I/O • Unblocked khi hệ điều hành hoàn thành I/O – WaitSleepJoin: • Xảy ra khi: – Tiến trình gọi Monitor phương thức Wait vì nó gặp mã mà nó không thực hiện được » Leaves khi một tiến trình khác gọi Pulse – Gọi phương thức Sleep để sleep trong một khoảng thời gian – Hai tiến trình dược kết hợp nếu một tiến trình không thể thực hiện cho đến khi tiến trình kia hoàn thành • Các tiến trình đợi (Waiting) hoặc ngủ (Sleeping) có thể ra khỏi trạng thái này nếu phương thức Interrupt của tiến trình được gọi 9 Các trạng thái tiến trình: Chu trình của một tiến trình • Trạng thái tiến trình: – Tạm ngưng (Suspended): • Khi phương thức Suspend được gọi • Trở về trạng thái bắt đầu (Started) khi phương thức Resume được gọi 10 Các trạng thái tiến trình: Chu trình của một tiến trình Unstarted Start Started dispatch quantum (assign a expiration processor) Running WaitSleepJoin Suspended Stopped Blocked Resume 11 Chu trình của một tiến trình NỘI DUNG CHÍNH 1 Giới thiệu tiến trình 2 Đa tiến trình trên .NET 3 Quản lý tiến trình 4 Đồng bộ hóa 12 Đa tiến trình trong .NET • Hầu hết các ngôn ngữ chỉ cho phép thực hiện một câu lệnh tại một thời điểm – Thông thường việc thực thi các câu lệnh một cách đồng thời chỉ bằng cách dùng hệ điều hành • Thư viện .NET Framework cho phép xử lý đồng thời bằng đa tiến trình – Đa tiến trình: thực thi các tiến trình đồng thời – Tiến trình: phần của một chương trình mà có thể thực thi 13 Tạo tiến trình • Lớp quản lý tiến trình: Thread • Constructor của Thread nhận tham số là 1 delegate kiểu ThreadStart public delegate void ThreadStart( ); • Hàm đầu vào của delegate là hàm để tiến trình thực thi Thread myThread = new Thread( new ThreadStart(myFunc) ); myThread.Start(); //Chạy tiến trình • Khi hàm chạy xong, tiến trình sẽ tự động kết thúc và hủy 14 Join tiến trình • Để tiến trình A tạm dừng và chờ tiến trình B hoàn thành thì mới tiếp tục, ta đặt hàm Join trong hàm thực thi của tiến trình A public void myFunc () { Dừng ở đây cho đến khi thread thB kết thúc … thB.Sleep(1000); • Tham số đưa vào được tính theo ms • Có thể dùng hàm Sleep để hệ điều hành chuyển quyền điều khiển sang một tiến trình khác Thread.WriteLine("[{0}] Interrupted! Cleaning up.Name); } 17 NỘI DUNG CHÍNH 1 Giới thiệu tiến trình 2 Đa tiến trình trên .NET 3 Quản lý tiến trình 4 Đồng bộ hóa 18 Background và Foreground • Một tiểu trình có thể được thực thi theo hai cách: background hoặc foreground.
• Một tiểu trình background được hoàn thành khi ứng dụng được kết thúc, ngược lại tiểu trình chạy foreground thì không phải chờ đợi sự kết thúc của ứng dụng. • Có thể thiết lập sự thực thi của tiểu trình bằng cách sử dụng thuộc tính IsBackground (true or false) 19 Độ ưu tiên tiến trình và lập lịch cho tiến trình • Tất cả tiến trình đều có một độ ưu tiên: – Các độ ưu tiên là: • Thấp nhất(Lowest) • Dưới trung bình(BelowNormal) • Trung bình(Normal) • Trên trung bình(AboveNormal) • Cao nhất(Highest) – Tất cả tiến trình mặc định là có độ ưu tiên trung bình – Sử dụng thuộc tính Priority để thay đổi độ ưu tiên của tiến trình 20 Độ ưu tiên tiến trình và lập lịch cho tiến trình • Timeslicing: – Mỗi tiến trình được cấp một khoảng thời gian để thực thi trước khi bộ xử lý được giao cho tiến trình khác – Nếu không có thì các tiến trình sẽ thực hiện cho đến lúc hoàn thành trước khi tiến trình khác bắt đầu thực thi • Lưu ý: – Mỗi luồng có 1 độ ưu tiên cơ sở. Những giá trị này liên quan đến độ ưu tiên trong tiến trình. – Một luồng có độ ưu tiên cao hơn đảm bảo nó sẽ chiếm quyền ưu tiên so với các luồng khác trong tiến trình.
– Windows có khuynh hướng đặt độ ưu tiên cao cho các luồng hệ điều hành của riêng nó. 21 Độ ưu tiên tiến trình và lập lịch cho tiến trình • Bộ lập lịch tiến trình: – Giữ tiến trình có độ ưu tiên cao nhất luôn thực thi tại mọi thời điểm • Nếu nhiều tiến trình có cùng độ ưu tiên: thực hiện xoay vòng – Đôi khi gây ra thiếu hụt: • Sự trì hoãn việc thực thi của một tiến trình có độ ưu tiên thấp 22 Độ ưu tiên tiến trình và lập lịch cho tiến trình Ready threads Priority Highest A B Priority AboveNormal C Priority Normal Priority BelowNormal D E F Priority Lowest G Lập lịch độ ưu tiên tiến trình 23 1 2 // Fig.cs // Multiple threads printing at different intervals.cs 3 4 using System; 5 using System.Threading; 6 Class that creates 7 // class ThreadTester demonstrates basic threading concepts 3 new threads 8 class ThreadTester 9 { 10 static void Main( string[] args ) 11 { 12 // Create and name each thread. Use MessagePrinter's 13 // Print method as argument to ThreadStart delegate. Create MessagePrinter 14 MessagePrinter printer1 = new MessagePrinter(); objects 15 Thread thread1 = 16 new Thread ( new ThreadStart( printer1.Name = "thread1"; 18 19 MessagePrinter printer2 = new MessagePrinter(); Create and initialize threads 20 Thread thread2 = 21 new Thread ( new ThreadStart( printer2.Name = "thread2"; Set thread’s name 23 24 MessagePrinter printer3 = new MessagePrinter(); Thread delegates 25 Thread thread3 = 26 new Thread ( new ThreadStart( printer3.Name = "thread3"; 28 29 Console.WriteLine( "Starting threads" ); 30 31 // call each thread's Start method to place each 32 // thread in Started state 33 thread1.Start(); Start threads 34 thread2.WriteLine( "Threads started\n" ); Tell user 38 39 } // end method Main threads started 40 41 } // end class ThreadTester 42 43 // Print method of this class used to control threads Class to define 44 class MessagePrinter Random sleep action of threads 45 { 46 private int sleepTime; time for thread 47 private static Random random = new Random(); 48 49 // constructor to initialize a MessagePrinter object Thread constructor 50 public MessagePrinter() 51 { 52 // pick random sleep time between 0 and 5 seconds Set sleep time 53 sleepTime = random.Next( 5001 ); 54 } 55 56 // method Print controls thread that prints messages 57 public void Print() 58 { Reference to 59 // obtain reference to currently executing thread current thread 60 Thread current = Thread.CurrentThread; 61 62 // put thread to sleep for sleepTime amount of time 63 Console.WriteLine( Print name of thread 64 current.Name + " going to sleep for " + sleepTime ); and sleep time 65 66 Thread.Sleep ( sleepTime ); Put thread to sleep 67 25 ThreadTester.cs 68 // print thread name 69 Console.Name + " done sleeping" ); 70 71 } // end method Print Tell user thread 72 is done sleeping 73 } // end class MessagePrinter Starting threads Threads started thread1 going to sleep for 1977 thread2 going to sleep for 4513 thread3 going to sleep for 1261 thread3 done sleeping thread1 done sleeping thread2 done sleeping Starting threads Threads started thread1 going to sleep for 1466 thread2 going to sleep for 4245 thread3 going to sleep for 1929 thread1 done sleeping thread3 done sleeping thread2 done sleeping 26 ThreadPool • Nếu ứng dụng sử dụng nhiều tiểu trình có thời gian sống ngắn hay duy trì một số lượng lớn các tiểu trình đồng thời thì hiệu năng có thể giảm sút bởi các chi phí cho việc tạo, vận hành và hủy các tiểu trình.