Bài giảng Nguyên lý hệ điều hành
Bạn đang xem 20 trang mẫu của tài liệu "Bài giảng Nguyên lý hệ điều hành", để tải tài liệu gốc về máy bạn click vào nút DOWNLOAD ở trên
Tài liệu đính kèm:
- bai_giang_nguyen_ly_he_dieu_hanh.pdf
Nội dung text: Bài giảng Nguyên lý hệ điều hành
- MỤC LỤC Chương 1: TỔNG QUAN 4 1.1 Giới thiệu 4 1.1.1 Hệ điều hành là gì? 4 1.1.2 Các hệ xử lý theo lô đơn giản 7 1.1.3 Các hệ xử lý theo lô, đa chương 8 1.1.4 Các hệ phân chia thời gian 9 1.1.5 Các hệ máy tính cá nhân 11 1.1.6 Các hệ song song, các hệ phân tán, các hệ thời gian thực 11 1.2 Cấu trúc hệ điều hành 15 1.2.1 Các thành phần hệ thống 16 1.2.2 Các dịch vụ của hệ điều hành 22 1.2.3 Lời gọi hệ thống 24 1.2.4 Các chương trình hệ thống 25 1.2.5 Cấu trúc hệ thống 26 1.2.6 Cài đặt và thiết kế hệ thống 33 Câu hỏi và bài tập chương 1 35 Chương 2: QUẢN LÝ TIẾN TRÌNH 36 2.1 Tiến tình 36 2.1.1 Khái niệm tiến trình 36 2.1.2 Lập lịch tiến trình 39 2.1.3 Các thao tác trên tiến trình 45 2.1.4 Hợp tác giữa các tiến trình 49 2.1.5 Luồng 52 2.1.6 Truyền thông giữa các tiến trình 70 2.2 Lập lịch CPU 74 2.2.1 Các khái niệm cơ bản 74 2.2.2 Các tiêu chí lập lịch 78 2.2.3 Các thuật toán lập lịch 79 2.2.4 Đánh giá thuật toán 95 2.3 Đồng bộ hóa tiến trình 96 2.3.1 Cơ sở 96 2.3.2 Bài toán Critical - Sestion 99 2.3.4 Các bài toán cổ điển trong việc đồng bộ hoá 114 2.4 Bế tắc 126 2.4.1 Mô hình 126 2.4.2 Đặc trưng hóa bế tắc 128 2.4.3 Các phương pháp thao tác với bế tắc 132 2.4.4 Phòng tránh bế tắc 136 2.4.5 Phát hiện bế tắc 144 2.4.6 Khôi phục từ bế tắc 148 1
- Câu hỏi và bài tập chương 2 150 Chương 3: QUẢN LÝ LƯU TRỮ 155 3.1 Quản lý bộ nhớ 155 3.1.1 Cơ sở 155 3.1.2 Bộ nhớ vật lý và bộ nhớ logic 160 3.1.3 Hoán vị (Swap) 161 3.1.4 Cấp phát liên tục 163 3.1.5 Phân trang 172 3.1.6 Phân đoạn 188 3.2 Bộ nhớ ảo 198 3.2.1 Cơ sở 198 3.2.2 Phân trang theo yêu cầu 201 3.2.3 Hiệu năng của phân trang theo yêu cầu 205 3.2.4 Thay thế trang 205 3.2.5 Các thuật toán thay thế trang 207 3.2.6 Cấp phát frame 215 3.2.7 Thrashing 218 3.2.8 Các vấn đề khác 220 3.2.9 Phân đoạn theo yêu cầu 221 3.3 Giao diện hệ thống tệp 225 3.3.1 Khái niệm tệp 225 3.3.2 Các phương pháp truy cập 229 3.3.3 Cấu trúc thư mục 231 3.3.4 Bảo vệ 243 3.3.5 Tính nhất quán về ngữ nghĩa 246 3.4 Cài đặt hệ thống tệp 246 3.4.1 Cấu trúc hệ thống tệp 247 3.4.2 Các phương pháp cấp phát 249 3.4.3 Quản lý không gian rỗi 260 3.4.4 Cài đặt thư mục 262 3.4.5 Hiệu quả và hiệu năng 264 3.4.6 Khôi phục 265 Câu hỏi và bài tập chương 3 265 Chương 4: HỆ VÀO RA 271 4.1 Hệ vào ra 271 4.1.1 Tổng quan 271 4.1.2 Vào ra phần cứng 272 4.1.3 Giao diện lập trình vào ra 275 4.1.4 Hệ vào ra của nhân 277 4.1.5 Chuyển đổi yêu cầu vào ra thành các thao tác phần cứng 281 4.1.6 Hiệu năng 283 4.2 Cấu trúc lưu trữ phụ 285 4.2.1 Cấu trúc đĩa 285 2
- 4.2.2 Lập lịch đĩa 286 4.2.3 Quản lý đĩa 290 4.2.4 Quản lý không gian swap 292 4.2.5 Độ tin cậy của đĩa 292 4.2.6 Cài đặt hệ lưu trữ ổn định 294 4.2.7 Các thiết bị lưu trữ thứ ba: Các công việc của hệ điều hành và vấn đề về hiệu năng 294 Câu hỏi và bài tập chương 4 297 TÀI LIỆU THAM KHẢO 300 3
- Chương 1: TỔNG QUAN 1.1 Giới thiệu Hệ điều hành là một chương trình phần mềm quản lý phần cứng máy tính. Nó cung cấp nền tảng cho các chương trình ứng dụng và đóng vai trò trung gian giao tiếp giữa người dùng máy tính và phần cứng của máy tính đó. Hệ điều hành thực hiện các nhiệm vụ rất đa dạng, một vài hệ điều hành được thiết kế để thực hiện một nhiệm vụ chuyên biệt nào đó trong khi một số hệ điều hành khác được thiết kế đa năng. 1.1.1 Hệ điều hành là gì? Một hệ điều hành là một thành phần quan trọng của mọi hệ thống máy tính. Một hệ thống máy tính có thể được chia thành bốn thành phần: phần cứng, hệ điều hành, các chương trình ứng dụng và người sử dụng. - Phần cứng (hardware): bao gồm bộ xử lý trung tâm (CPU), bộ nhớ (memory), thiết bị xuất/nhập (I/O), cung cấp tài nguyên cơ bản cho hệ thống. - Các chương trình ứng dụng (application programs): trình biên dịch (compiler), trình soạn thảo văn bản (text editor), hệ cơ sở dữ liệu (database system), trình duyệt Web, hỗ trợ người dùng sử dụng tài nguyên, giải quyết yêu cầu của người dùng. - Người dùng (user): là người sử dụng hệ thống, những người dùng khác nhau thực hiện những yêu cầu khác nhau bằng các ứng dụng khác nhau. - Hệ điều hành (operating system): hay còn gọi là chương trình hệ thống, điều khiển và phối hợp việc sử dụng phần cứng giữa những chương trình ứng dụng khác nhau cho những người dùng khác nhau. Hệ điều hành có thể được khai thác từ hai phía: người dùng và hệ thống. User 1 User 2 User N Compliler Text editor Database System and application programs Operating System Hardwave Hình 1.1 Các thành phần của một hệ thống máy tính 4
- + Tầm nhìn người sử dụng Tầm nhìn người sử dụng máy tính rất đa dạng bởi giao diện được dùng. Hầu hết những người dùng máy tính ngồi trước máy tính cá nhân gồm có màn hình, bàn phím, chuột và bộ xử lý hệ thống (system unit). Một hệ thống như thế được thiết kế cho một người dùng độc quyền sử dụng tài nguyên của nó để tối ưu hoá công việc mà người dùng đang thực hiện. Trong trường hợp này, hệ điều hành được thiết kế dễ dàng cho việc sử dụng với sự quan tâm về năng lực thực hiện ít quan tới việc sử dụng tài nguyên. Có người sử dụng ngồi tại thiết bị đầu cuối (terminal) được nối kết tới máy tính lớn (mainframe) hay máy tính tầm trung (minicomputer). Những người khác đang truy xuất cùng máy tính thông qua các thiết bị đầu cuối khác. Những người dùng này chia sẻ các tài nguyên và có thể trao đổi thông tin. Hệ điều hành được thiết kế để tối ưu hoá việc sử dụng tài nguyên để đảm bảo rằng tất cả thời gian phục vụ của CPU, bộ nhớ và thiết bị xuất nhập được sử dụng hữu hiệu, công bằng. Gần đây, các máy tính xách tay được sử dụng rộng rãi. Các thiết bị này được sử dụng chỉ bởi cá nhân người dùng. Một vài máy tính này được nối mạng hoặc nối trực tiếp bằng cáp mạng hay thông qua các modem không dây. Do sự giới hạn về năng lượng, hệ điều hành được thiết kế để tiết kiệm tối đa năng lượng của máy tính. Một số máy tính có rất ít hay không có giao diện với người dùng. Thí dụ, các máy tính được nhúng vào các thiết bị gia đình và xe ôtô có thể có một bảng số và các đèn hiển thị trạng thái mở, tắt nhưng hầu hết chúng và các hệ điều hành được thiết kế để điều khiển thiết bị không cần giao tiếp với ngưới sử dụng. + Tầm nhìn hệ thống Chúng ta có thể thấy một hệ điều hành như bộ cấp phát tài nguyên. Hệ thống máy tính có nhiều tài nguyên - phần cứng và phần mềm - có thể được yêu cầu để cấp phát các tài nguyên: thời gian CPU, không gian bộ nhớ, không gian lưu trữ tập tin, các thiết bị xuất/nhập, Hệ điều hành hoạt động như bộ quản lý tài nguyên, thực hiện một lượng lớn các yêu cầu cấp phát có thể xung đột về tài nguyên, hệ điều hành phải quyết định cách cấp phát tài nguyên tới những chương trình cụ thể và người dùng để có thể điều hành hệ thống máy tính hữu hiệu và công bằng. 5
- Một tầm nhìn khác của hệ điều hành nhấn mạnh sự cần thiết để điều khiển các thiết bị xuất/nhập khác nhau và chương trình người dùng. Một hệ điều hành là một chương trình điều khiển. Chương trình điều khiển quản lý sự thực hiện của các chương trình người dùng để ngăn chặn lỗi và việc sử dụng không hợp lý máy tính. Nó đặc biệt quan tâm với những thao tác và điều khiển các thiết bị nhập/xuất. Nhìn chung, không có định nghĩa hoàn toàn đầy đủ về hệ điều hành. Các hệ điều hành tồn tại vì chúng là cách hợp lý để giải quyết vấn đề tạo ra một hệ thống máy tính có thể sử dụng. Mục tiêu cơ bản của hệ thống máy tính là thực hiện chương trình người dùng và giải quyết các vấn đề để người dùng dễ dàng sử dụng hệ thống máy tính hơn. Hướng đến mục tiêu này, phần cứng máy tính được xây dựng. Tuy nhiên, chỉ đơn thuần là phần cứng thì không dễ sử dụng và phát triển các chương trình ứng dụng. Các chương trình ứng dụng khác nhau này đòi hỏi những thao tác chung nào đó, chẳng hạn như điều khiển thiết bị xuất/nhập. Sau đó, những chức năng chung về điều khiển và cấp phát tài nguyên được đặt lại với nhau vào một bộ phận phần mềm gọi là hệ điều hành. Mục đích chính của hệ điều hành là giúp người sử dụng dễ dàng hơn trong việc sử dụng hệ thống máy tính. Vì sự tồn tại của hệ điều hành hỗ trợ rất nhiều cho máy tính trong việc đáp ứng các ứng dụng của người dùng. Điều này đặc biệt rõ ràng hơn khi xem xét hệ điều hành trên các máy tính cá nhân. Mục tiêu thứ hai của hệ điều hành là điều hành hiệu quả hệ thống máy tính. Mục tiêu này đặc biệt quan trọng cho các hệ thống lớn, được chia sẻ, nhiều người dùng. Những hệ thống tiêu biểu này khá đắt, khai thác hiệu quả nhất các hệ thống này luôn là điều mong muốn. Tuy nhiên, hai mục tiêu tiện dụng và hữu hiệu đôi khi mâu thuẫn nhau. Trong quá khứ, xem xét tính hữu hiệu thường quan trọng hơn tính tiện dụng. Do đó, lý thuyết hệ điều hành tập trung nhiều vào việc tối ưu hoá sử dụng tài nguyên tính toán. Hệ điều hành cũng phát triển dần theo thời gian. Thí dụ, UNIX bắt đầu với bàn phím và máy in như giao diện của nó giới hạn tính tiện dụng đối với người dùng. Qua thời gian, phần cứng thay đổi và UNIX được gắn vào phần cứng mới với giao diện thân thiện với người dùng hơn. Nhiều giao diện người dùng đồ hoạ GUIs (graphical user interfaces) được bổ sung cho phép tiện dụng hơn với người dùng trong khi vẫn quan tâm tính hiệu quả. 6
- 1.1.2 Các hệ xử lý theo lô đơn giản Những hệ thống máy tính mainframe là những máy tính đầu tiên được dùng để xử lý ứng dụng thương mại và khoa học. Trong phần này, chúng ta lần theo sự phát triển của hệ thống mainframe từ các hệ thống bó (batch systems), ở đó máy tính chỉ chạy một-và chỉ một -ứng dụng, tới các hệ thống chia sẻ thời gian (time-shared systems), ở đó cho phép người dùng giao tiếp với hệ thống máy tính. Những máy tính thời kỳ đầu là những máy có kích thước rất lớn và được chạy từ một thiết bị cuối (console). Những thiết bị nhập thường sử dụng là những bộ đọc thẻ, các ổ đĩa và băng từ. Các thiết bị xuất thông thường thường là những máy in dòng (line printers), các ổ đĩa từ và các phiếu đục lỗ. Người dùng không giao tiếp trực tiếp với các hệ thống máy tính. Thay vào đó, người dùng chuẩn bị một công việc - chứa chương trình, dữ liệu và các thông tin điều khiển về tính tự nhiên của công việc – sau đó gửi nó đến người điều hành máy tính. Công việc này thường được thực hiện trong các phiếu đục lỗ. Sau một thời gian (vài phút, giờ hay ngày), dữ liệu kết quả sẽ xuất hiện. Hệ điều hành trong các máy tính thời kỳ đầu này tương đối đơn giản. Nhiệm vụ chính là chuyển điều khiển tự động từ thực hiện công việc này sang công việc khác. Hệ điều hành luôn được thường trú trong bộ nhớ. Hệ điều hành Vùng chương trình người dùng Hình 1.2 Sắp xếp bộ nhớ cho một hệ thống bó đơn giản Để tăng tốc việc xử lý, người điều hành “bó” các công việc có cùng yêu cầu và chạy chúng thông qua máy tính như một nhóm. Do đó, các lập trình viên sẽ đưa chương trình của họ cho người điều hành. Người điều hành sẽ sắp xếp chương trình thành những “bó” với cùng yêu cầu và khi máy tính sẵn dùng sẽ chạy mỗi bó này. Dữ liệu xuất từ mỗi công việc sẽ gửi lại cho lập trình viên tương ứng. 7
- Trong môi trường thực hiện này, CPU luôn rỗi vì tốc độ của các thiết bị xuất/nhập dạng cơ thường chậm hơn tốc độ của các thiết bị điện. Một CPU chậm cũng có thể thực hiện hàng ngàn chỉ thị lệnh được thực hiện trên giây, trong khi đó một bộ đọc thẻ nhanh chỉ có thể đọc 1200 thẻ trong thời gian 1 phút (hay 20 thẻ trên giây). Do đó, sự khác biệt giữa tốc độ CPU và thiết bị xuất/nhập của nó có thể là 3 lần hay nhiều hơn. Theo thời gian, sự tiến bộ trong công nghệ dẫn đến sự ra đời những thiết bị nhập/xuất nhanh hơn. Tuy nhiên, tốc độ CPU tăng tới một tỷ lệ lớn hơn vì thế vấn đề không những không được giải quyết mà còn làm gia tăng cách biệt. Công nghệ đĩa từ cho phép hệ điều hành lưu giữ tất cả công việc trên một đĩa thay cho lưu giữ trong một bộ đọc thẻ tuần tự. Với việc truy xuất trực tiếp tới nhiều công việc trên đĩa từ, hệ điều hành có thể thực hiện lập lịch công việc, để sử dụng tài nguyên và thực hiện các công việc hiệu quả hơn. 1.1.3 Các hệ xử lý theo lô, đa chương Một vấn đề rất quan trọng trong lập lịch công việc là khả năng đa chương. Thông thường, một người sử dụng luôn muốn CPU và các thiết bị xuất/nhập luôn bận, tận dụng tối đa hiệu suất của các thiết bị phần cứng. Đa chương sẽ làm gia tăng khả năng sử dụng CPU bằng cách tổ chức các công việc để CPU luôn có một công việc cần thực hiện. Ý tưởng của kỹ thuật đa chương có thể minh hoạ như sau: tại một thời điểm, hệ điều hành giữ nhiều công việc trong bộ nhớ trong. Tập hợp các công việc này là tập con của các công việc được giữ trong vùng công việc - bởi vì số lượng các công việc có thể được giữ cùng lúc trong bộ nhớ thường nhỏ hơn số công việc có thể có trong vùng đệm. Hệ điều hành sẽ lấy và bắt đầu thực hiện một trong các công việc có trong bộ nhớ. Khi công việc phải chờ một vài tác vụ như một thao tác xuất/nhập để hoàn thành, trong hệ thống đơn chương, CPU sẽ chờ ở trạng thái rỗi, còn trong hệ thống đa chương, hệ điều hành sẽ chuyển sang thực hiện công việc khác. Cuối cùng, công việc đầu tiên kết thúc việc chờ và nhận CPU để thực hiện tiếp. Chỉ cần có ít nhất một công việc đang đợi để thực hiện, CPU sẽ không bao giờ ở trạng thái rỗi. 8
- Hệ điều hành Công việc 1 Công việc 2 Công việc 3 Công việc 4 Hình 1.3 Sắp xếp bộ nhớ cho hệ đa chương Đa chương là một trường hợp đầu tiên mà hệ điều hành phải thực hiện quyết định thay cho những người sử dụng, do đó, hệ điều hành đa chương tương đối phức tạp. Tất cả công việc đưa vào hệ thống được giữ trong vùng công việc. Vùng này chứa tất cả tiến trình lưu trữ trên đĩa cứng chờ được cấp phát bộ nhớ chính. Nếu nhiều công việc đang chờ sẵn sàng để được đưa vào bộ nhớ và nếu không đủ không gian cho tất cả công việc thì hệ điều hành phải chọn một công việc trong tập các công việc đang đợi. Khi hệ điều hành chọn một công việc từ vùng công việc, nó nạp công việc đó vào bộ nhớ để thực hiện. Có nhiều chương trình trong bộ nhớ tại cùng thời điểm yêu cầu phải có sự quản lý bộ nhớ. Ngoài ra, nếu nhiều công việc sẵn sàng chạy cùng thời điểm, hệ thống phải chọn một trong chúng. Thực hiện quyết định này là lập lịch CPU. Cuối cùng, nhiều công việc chạy đồng hành đòi hỏi hoạt động của chúng có thể ảnh hưởng tới một công việc khác thì bị hạn chế trong tất cả giai đoạn của hệ điều hành bao gồm lập lịch tiến trình, lưu trữ đĩa, quản lý bộ nhớ. 1.1.4 Các hệ phân chia thời gian Hệ thống đa chương cung cấp một môi trường nơi mà nhiều tài nguyên khác nhau (chẳng hạn như CPU, bộ nhớ, các thiết bị ngoại vi) được sử dụng hiệu quả. Tuy nhiên, nó không cung cấp giao tiếp người dùng với hệ thống máy tính. Hệ điều hành đa nhiệm là sự mở rộng logic của đa chương. CPU thực hiện nhiều công việc bằng cách chuyển đổi qua lại giữa chúng, nhưng những chuyển đổi xảy ra rất thường xuyên để người dùng có thể giao tiếp với mỗi chương trình trong khi các chương trình thực hiện. 9
- Một hệ thống máy tính cung cấp giao tiếp trực tiếp giữa người dùng và hệ thống. Người dùng cho những chỉ thị tới hệ điều hành hay trực tiếp tới một chương trình, sử dụng bàn phím hay chuột và chờ nhận kết quả. Do đó, thời gian đáp ứng rất ngắn, thường trong phạm vi dưới một giây. Một hệ điều hành đa nhiệm (phân chia thời gian) sử dụng lập lịch CPU và đa chương để cung cấp mỗi người dùng với một phần nhỏ việc tính toán của máy tính trong mỗi thời điểm. Mỗi người dùng có ít nhất một chương trình riêng trong bộ nhớ. Một chương trình được nạp vào trong bộ nhớ và thực hiện thường được gọi là một tiến trình. Khi một tiến trình thực hiện, thông thường nó chỉ thực hiện trong một thời gian ngắn trước khi nó kết thúc hay cần thực hiện xuất/nhập. Xuất/nhập có thể được giao tiếp; nghĩa là dữ liệu xuất hiển thị trên màn hình cho người dùng và dữ liệu nhập từ bàn phím, chuột hay thiết bị khác. Vì giao tiếp xuất/nhập chủ yếu chạy ở tốc độ chậm, do đó nó có thể mất một khoảng thời gian dài để hoàn thành. Thí dụ, dữ liệu nhập có thể bị giới hạn bởi tốc độ nhập của người dùng; 7 ký tự trên giây là nhanh đối với người dùng, nhưng quá chậm so với máy tính. Thay vì để CPU rỗi khi người dùng nhập dữ liệu, hệ điều hành sẽ nhanh chóng chuyển CPU tới một tiến trình khác. Hệ điều hành đa nhiệm phức tạp hơn nhiều so với hệ điều hành đa chương. Trong cả hai dạng, nhiều công việc được giữ cùng lúc trong bộ nhớ vì thế hệ thống phải có cơ chế quản lý bộ nhớ và bảo vệ. Để đạt được thời gian đáp ứng hợp lý, các công việc có thể được hoán vị vào ra bộ nhớ chính. Một phương pháp chung để đạt mục tiêu này là bộ nhớ ảo, là kỹ thuật cho phép việc thực hiện của một công việc có thể không hoàn toàn ở trong bộ nhớ. Ưu điểm chính của cơ chế bộ nhớ ảo là các chương trình có thể lớn hơn bộ nhớ vật lý. Ngoài ra, nó trừu tượng hoá bộ nhớ chính thành mảng lưu trữ lớn và đồng nhất, chia bộ nhớ logic như được thấy bởi người dùng từ bộ nhớ vật lý. Sự sắp xếp này giúp cho lập trình viên không phải quan tâm đến giới hạn lưu trữ của bộ nhớ. Các hệ đa nhiệm cũng phải cung cấp một hệ thống tập tin. Hệ thống tập tin định vị trên một tập hợp đĩa; do đó quản lý đĩa phải được cung cấp. Hệ đa nhiệm cũng cung cấp cơ chế cho việc thực hiện đồng hành, yêu cầu cơ chế lập lịch CPU tinh vi. Để đảm bảo thứ tự thực hiện, hệ thống phải cung cấp các cơ chế cho việc đồng bộ hoá 10
- và giao tiếp công việc, và có thể đảm bảo rằng các công việc không bị deadlock, tức là chờ đợi công việc khác mãi mãi. Ý tưởng đa nhiệm được giới thiệu trong những năm 1960, nhưng vì hệ đa nhiệm là phức tạp và rất đắt để xây dựng, chúng không phổ biến cho tới những năm 1970. Mặc dù xử lý theo lô vẫn được thực hiện nhưng hầu hết hệ thống ngày nay là đa nhiệm. Do đó, đa chương và đa nhiệm là những chủ đề chính của hệ điều hành hiện đại. 1.1.5 Các hệ máy tính cá nhân Trong suốt thập niên đầu khi máy tính cá nhân (PC) xuất hiện, CPU trong PC thiếu các đặc điểm cần thiết để bảo vệ hệ điều hành từ chương trình người dùng. Do đó, các hệ điều hành PC không thực hiện được đa người dùng hoặc đa nhiệm. Tuy nhiên, các mục tiêu của hệ điều hành này thay đổi theo thời gian; thay vì tối ưu hoá việc sử dụng CPU và thiết bị ngoại vi, các hệ thống chọn lựa tối ưu hoá sự tiện dụng và đáp ứng người dùng. Các hệ thống này gồm các PC chạy các hệ điều hành Microsoft Windows và Apple Macintosh. Hệ điều hành MS-DOS từ Microsoft được thay thế bằng nhiều ấn bản của Microsoft Windows và IBM đã nâng cấp MS-DOS thành hệ đa nhiệm OS/2. Hệ điều hành Apple Macintosh được gắn nhiều phần cứng hiện đại hơn và ngày nay chứa nhiều đặc điểm mới như bộ nhớ ảo và đa nhiệm. Với sự phát hành MacOS X, lõi của hệ điều hành ngày nay dựa trên Mach và FreeBSD UNIX cho sự mở rộng, năng lực và đặc điểm nhưng nó vẫn giữ lại giao diện đồ hoạ người dùng GUI. LINUX, một hệ điều hành tương tự như UNIX sử dụng cho máy PC trở nên phổ biến gần đây. 1.1.6 Các hệ song song, các hệ phân tán, các hệ thời gian thực 1) Hệ đa xử lý Hầu hết các hệ thống ngày nay là các hệ thống đơn xử lý; nghĩa là chỉ có một CPU trong hệ thống. Tuy nhiên, các hệ thống đa xử lý được phát triển rất mạnh, các hệ thống như thế có nhiều hơn một bộ xử lý. Hệ thống đa xử lý có ba ưu điểm chính: + Thông lượng được gia tăng: bằng cách tăng số lượng bộ xử lý, có thể thực hiện nhiều công việc hơn với thời gian ít hơn. 11
- + Tính kinh tế của việc mở rộng: hệ thống đa xử lý có thể tiết kiệm nhiều chi phí hơn hệ thống đơn bộ xử lý, bởi vì chúng có thể chia sẻ thiết bị ngoại vi, thiết bị lưu trữ và năng lượng điện tiêu thụ. Nếu nhiều chương trình điều hành trên cùng tập hợp dữ liệu thì lưu trữ dữ liệu đó trên một đĩa và tất cả bộ xử lý chia sẻ chúng sẽ rẻ hơn là có nhiều máy tính với đĩa cục bộ và nhiều bản sao dữ liệu. + Khả năng tin cậy được gia tăng: nếu các chức năng được phân bổ hợp lý giữa các bộ xử lý thì lỗi trên một bộ xử lý sẽ không dừng hệ thống, chỉ năng lực bị giảm. Nếu chúng ta có 10 bộ xử lý và có 1 bộ xử lý bị sự cố thì mỗi bộ xử lý trong 9 bộ xử lý còn lại phải chia sẻ của công việc của bộ xử lý bị lỗi. Do đó, toàn bộ hệ thống chỉ giảm 10% năng lực chứ không dừng hoạt động. Các hệ thống được thiết kế như thế được gọi là hệ thống có khả năng chịu lỗi (fault tolerant). Các hệ thống đa xử lý thông dụng nhất hiện nay sử dụng đa xử lý đối xứng (symmetric multiprocessing). Trong hệ thống này mỗi bộ xử lý chạy bản sao của hệ điều hành và những bản sao này giao tiếp với các bản sao khác khi cần. Ngoài ra, còn có các hệ thống sử dụng đa xử lý bất đối xứng (asymmetric multiprocessing). Trong hệ thống này mỗi bộ xử lý được gán một công việc xác định. Một bộ xử lý chủ điều khiển hệ thống; những bộ xử lý còn lại hoặc chờ bộ xử lý chủ ra chỉ thị hoặc có những tác vụ được định nghĩa trước. Cơ chế này định nghĩa mối quan hệ chủ-tớ. Bộ xử lý chính lập thời biểu và cấp phát công việc tới các bộ xử lý tớ. Đa xử lý đối xứng có nghĩa tất cả bộ xử lý là ngang hàng; không có mối quan hệ chủ-tớ tồn tại giữa các bộ xử lý. (Hình 1.4) minh hoạ một kiến trúc đa xử lý đối xứng điển hình. Một thí dụ của đa xử lý đối xứng là ấn bản của Encore của UNIX cho máy tính Multimax. Máy tính này có thể được cấu hình như nó đang thực hiện nhiều bộ xử lý, tất cả bộ xử lý đều chạy bản sao của UNIX. Ưu điểm của mô hình này là nhiều tiến trình có thể chạy cùng một lúc n tiến trình có thể chạy nếu hệ thống có n CPU. Tuy nhiên, chúng ta phải điều khiển chính xác việc xuất/nhập để đảm bảo rằng dữ liệu dẫn tới bộ xử lý tương ứng. Vì các CPU là riêng rẽ, một CPU có thể đang rỗi trong khi CPU khác quá tải dẫn đến việc sử dụng không hiệu quả tài nguyên của hệ thống. Sự không hiệu quả này có thể tránh được nếu các bộ xử lý chia sẻ các cấu trúc dữ liệu. Một hệ thống đa xử lý của dạng này sẽ cho phép các tiến trình và tài nguyên – như bộ nhớ - được chia sẻ tự động giữa các tiến trình khác nhau và có thể làm giảm 12
- sự khác biệt giữa các bộ xử lý. Hầu như tất cả hệ điều hành hiện đại, như Windows NT, Solaris, Digital UNIX, OS/2 và LINUX hiện nay đều cung cấp sự hỗ trợ đa xử lý đối xứng. CPU CPU . CPU Memory Hình 1.4 Kiến trúc đa xử lý đối xứng Sự khác biệt giữa đa xử lý đối xứng và bất đối xứng có thể là do phần cứng hoặc phần mềm. Phần cứng đặc biệt có thể khác nhau trên nhiều bộ xử lý, hoặc phần mềm có thể được viết để cho phép chỉ một chủ và nhiều tớ. Thí dụ, SunOS phiên bản 4 cung cấp đa xử lý không đối xứng, nhưng phiên bản 5 là đối xứng trên cùng phần cứng. 2) Hệ phân tán Một mạng máy tính với cách nhìn đơn giản nhất, là một đường dẫn truyền thông giữa hai hay nhiều hệ thống máy tính. Hệ phân tán phụ thuộc vào mạng với những khả năng của nó. Bằng cách cho phép truyền thông, hệ phân tán có thể chia sẻ các công việc tính toán và cung cấp nhiều chức năng tới người dùng. Các mạng rất đa dạng về giao thức sử dùng, khoảng cách giữa các nút và phương tiện truyền. TCP/IP là giao thức mạng phổ biến nhất mặc dù ATM và các giao thức khác được sử dụng rất rộng rãi. Tương tự, hệ điều hành hỗ trợ sự đa dạng về giao thức. Hầu hết các hệ điều hành hỗ trợ TCP/IP như hệ điều hành Windows, LINUX và UNIX. Một số hệ điều hành khác hỗ trợ các giao thức riêng phù hợp với yêu cầu của chúng. Đối với một hệ điều hành, một giao thức mạng chỉ cần một thiết bị giao diện – thí dụ: một card mạng - với một trình điều khiển thiết bị để quản lý nó và một phần mềm để đóng gói dữ liệu trong giao thức giao tiếp để gửi nó và mở gói để nhận nó. 13
- 3) Hệ thống nhóm (Clustered Systems) Tương tự các hệ song song, hệ thống nhóm tập hợp nhiều CPUs với nhau để thực hiện công việc tính toán. Tuy nhiên, hệ thống nhóm khác hệ thống song song ở điểm chúng được hợp thành từ hai hay nhiều hệ thống đơn được kết hợp với nhau (thông thường liên kết qua mạng LAN) Nhóm thường được thực hiện để cung cấp khả năng sẵn sàng sử dụng cao. Một lớp phần mềm nhóm chạy trên các nút nhóm (cluster nodes), mỗi nút có thể kiểm soát một hay nhiều hơn một nút (qua mạng LAN). Nếu máy bị kiểm soát gặp sự cố, máy kiểm soát có thể lấy quyền sở hữu việc lưu trữ của nó và khởi động lại các ứng dụng mà chúng đang chạy trên máy bị sự cố. Máy bị sự cố vẫn chưa hoạt động nhưng người dùng và khách hàng của ứng dụng chỉ thấy một sự gián đoạn ngắn của dịch vụ. Trong nhóm bất đối xứng (asymmetric clustering), một máy ở trong chế độ dự phòng nóng (hot standby) trong khi các máy khác đang chạy các ứng dụng. Máy dự phòng không làm gì cả chỉ theo dõi server hoạt động. Nếu server đó bị lỗi, máy chủ dự phòng nóng trở thành server hoạt động. Trong chế độ đối xứng (symmetric mode), hai hay nhiều máy chủ đang chạy ứng dụng và chúng đang kiểm soát lẫn nhau. Chế độ này chú trọng tính hiệu quả khi nó sử dụng tất cả phần cứng sẵn có. Nó thực hiện yêu cầu nhiều hơn một ứng dụng sẵn dùng để chạy. Các hình thức khác của nhóm gồm các nhóm song song (parallel clusters) và nhóm qua một WAN. Các nhóm song song cho phép nhiều máy chủ truy xuất cùng dữ liệu trên thiết bị lưu trữ được chia sẻ. Vì hầu hết các hệ điều hành hỗ trợ nghèo nàn việc truy xuất dữ liệu đồng thời bởi nhiều máy chủ, các nhóm song song thường được thực hiện bởi các ấn bản phần mềm đặc biệt và sự phát hành của các ứng dụng đặc biệt. Thí dụ, Oracle Parallel Server là một ấn bản cơ sở dữ liệu của Oracle, và lớp phần mềm ghi vết việc truy xuất tới đĩa được chia sẻ. Mỗi máy có truy xuất đầy đủ tới dữ liệu trong cơ sở dữ liệu. Mặc dù có nhiều cải tiến trong tính toán phân tán, hầu hết các hệ thống không cung cấp các hệ thống tập tin phân tán mục đích chung (general-purpose distributed file systems). Do đó, hầu hết các nhóm không cho phép truy xuất được chia sẻ tới dữ liệu trên đĩa. Cho mục đích này, các hệ thống tập tin phân tán phải cung cấp điều khiển truy xuất và khoá các tập tin để đảm bảo không có các thao tác xung đột xảy ra. 14
- Loại dịch vụ này thường được gọi là bộ quản lý khoá phân tán (distributed lock manager-DLM). 4) Hệ thời gian thực Một dạng khác của hệ điều hành có mục đích đặc biệt là hệ thời gian thực (real-time system). Hệ thời gian thực được dùng khi các yêu cầu thời gian khắt khe được đặt trên thao tác của một bộ xử lý hay dòng dữ liệu; do đó, nó thường được dùng như một thiết bị điều khiển trong một ứng dụng liên quan đến yếu tố thời gian. Các bộ cảm biến mang dữ liệu tới máy tính, máy tính phải phân tích dữ liệu và có thể thích ứng các điều khiển để hiệu chỉnh các dữ liệu nhập từ cảm biến. Các hệ thống điều khiển các thí nghiệm khoa học, hệ thống ảnh hoá y tế, hệ thống điều khiển công nghệ và các hệ thống hiển thị, Các hệ thống phun dầu động cơ ôtô, các bộ điều khiển dụng cụ trong nhà, hệ thống vũ khí cũng là các hệ thống thời thực. Một hệ thống thời thực có sự ràng buộc cố định, rõ ràng. Xử lý phải được thực hiện trong phạm vi các ràng buộc được định nghĩa hay hệ thống sẽ thất bại. Một hệ thời thực thực hiện đúng chức năng chỉ nếu nó trả về kết quả đúng trong thời gian ràng buộc. Tương phản với yêu cầu này trong hệ chia thời, ở đó nó mong muốn (nhưng không bắt buộc) đáp ứng nhanh, hay đối với hệ thống theo lô, nó không có ràng buộc thời gian. 1.2 Cấu trúc hệ điều hành Hệ điều hành cung cấp môi trường cho các chương trình thực hiện. Các hệ điều hành rất khác biệt nhau về kiến trúc, chúng được tổ chức cùng với các loại khác nhau. Thiết kế một hệ điều hành mới là một công việc quan trọng. Mục đích của hệ thống phải được định nghĩa rõ ràng trước khi thiết kế bắt đầu. Kiểu hệ thống mong muốn là cơ sở cho việc chọn lựa giữa các giải thuật và chiến lược khác nhau. Hệ điều hành có thể được xem xét từ nhiều góc nhìn khác nhau như: các dịch vụ mà hệ điều hành cung cấp; giao diện mà hệ điều hành cung cấp cho người dùng và người lập trình; những thành phần của hệ điều hành và các mối quan hệ bên trong của chúng. Trong chương này sẽ tìm hiểu cả ba khía cạnh của hệ điều hành, thể hiện ba quan điểm của người dùng, người lập trình và người thiết kế hệ điều hành. Chúng ta xem xét các dịch vụ mà hệ điều hành cung cấp, cách chúng được cung cấp và các phương pháp khác nhau được dùng cho việc thiết kế hệ điều hành. 15
- 1.2.1 Các thành phần hệ thống Chỉ có thể tạo ra một hệ thống lớn và phức tạp như hệ điều hành khi phân chia hệ điều hành thành những phần nhỏ hơn có độ phức tạp ít hơn. Mỗi phần nên là một thành phần được mô tả rõ ràng của hệ thống, với xuất, nhập và các chức năng được định nghĩa đầy đủ. Thông thường, các hệ điều hành được chia thành các thành phần sau: 1) Quản lý tiến trình Một chương trình chỉ được thực hiện khi các chỉ thị của chương trình được một bộ xử lý trung tâm (CPU) thực hiện. Một tiến trình là một chương đang thực hiện. Một tiến trình cần các tài nguyên xác định gồm thời gian CPU, bộ nhớ, tập tin, các thiết bị xuất/nhập để hoàn thành nhiệm vụ của nó. Các tài nguyên này được cấp cho tiến trình khi tiến trình được khởi tạo, hay được cấp phát cho tiến trình khi tiến trình đang thực hiện. Các tài nguyên được cấp phát cho các tiến trình có thể là tài nguyên vật lý hoặc tài nguyên logic. Khi tiến trình kết thúc, hệ điều hành sẽ thu hồi tất cả tài nguyên đã cấp cho tiến trình. Chú ý là một chương trình không phải là một tiến trình, một chương trình là một thực thể thụ động, như là nội dung của tập tin được lưu trên đĩa. Ngược lại với chương trình, một tiến trình là một thực thể hoạt động, được nạp vào bộ nhớ trong, với con trỏ lệnh xác định chỉ thị tiếp theo sẽ được thực hiện. Việc thực hiện của tiến trình phải là tuần tự. CPU thực hiện một chỉ thị của tiến trình sau khi đã thực hiện một chỉ thị trước đó, lần lượt cho đến khi tiến trình hoàn thành. Ngoài ra, tại bất kỳ thời điểm nào, với một tiến tỉnh chỉ có tối đa chỉ một chỉ thị được thực hiện. Một tiến trình là một đơn vị công việc trong hệ thống. Một hệ thống chứa tập các tiến trình, một vài tiến trình này là các tiến trình của hệ điều hành (thực hiện các mã lệnh của hệ thống) các tiến trình còn lại là các tiến trình người dùng (chúng thực hiện các mã lệnh của người dùng). Chức năng quản lý tiến trình của hệ điều hành gồm các nhiệm vụ sau: + Tạo và xoá các tiến trình người dùng và hệ thống + Tạm dừng và thực hiện tiếp tiến trình + Cung cấp các cơ chế đồng bộ hoá tiến trình 16
- + Cung cấp các cơ chế giao tiếp tiến trình + Cung cấp cơ chế quản lý khoá chết (deadlock) 2) Quản lý bộ nhớ chính Bộ nhớ chính là trung tâm điều hành của một máy tính hiện đại. Bộ nhớ chính là một mảng các từ (words) hay bytes có kích thước lớn. Mỗi từ hay byte có địa chỉ riêng. Bộ nhớ chính là một kho chứa dữ liệu có khả năng truy xuất nhanh được chia sẻ bởi CPU và các thiết bị xuất/nhập. Bộ xử lý trung tâm đọc các chỉ thị từ bộ nhớ trong chu kỳ lấy chỉ thị, nó đọc và viết dữ liệu từ bộ nhớ chính trong chu kỳ lấy dữ liệu. Bộ nhớ chính thường là thiết bị lưu trữ lớn mà CPU có thể định địa chỉ và truy xuất trực tiếp. Thí dụ, đối với CPU xử lý dữ liệu từ đĩa, dữ liệu trước tiên được chuyển tới bộ nhớ chính bởi lời gọi xuất/nhập được sinh ra bởi CPU. Tương tự, các chỉ thị phải ở trong bộ nhớ cho CPU thực hiện chúng. Đối với một chương trình được thực hiện, nó phải được ánh xạ các địa chỉ và được nạp vào bộ nhớ. Khi chương trình thực hiện, nó truy xuất các chỉ thị chương trình và dữ liệu từ bộ nhớ bằng cách tạo ra các địa chỉ tuyệt đối này. Cuối cùng, chương trình kết thúc, không gian bộ nhớ của sẽ được thu hồi, và chương trình tiếp theo có thể được nạp và thực hiện. Để cải tiến việc sử dụng CPU và tốc độ đáp ứng của máy tính cho người dùng, chúng ta phải giữ nhiều chương trình trong bộ nhớ. Nhiều cơ chế quản lý bộ nhớ khác nhau được dùng và tính hiệu quả của các giải thuật phụ thuộc vào từng trường hợp cụ thể. Chọn một cơ chế quản lý bộ nhớ cho một hệ thống xác định phụ thuộc vào nhiều yếu tố-đặc biệt trên thiết kế phần cứng của hệ thống. Mỗi giải thuật đòi hỏi sự hỗ trợ phần cứng của nó. Hệ điều hành có nhiệm vụ cho các hoạt động sau khi đề cập tới việc quản lý bộ nhớ + Lưu giữ xem phần nào của bộ nhớ hiện đang được sử dụng và tiến trình nào đang dùng. + Quyết định tiến trình nào được nạp vào bộ nhớ khi không gian bộ nhớ trở nên sẵn sàng. + Cấp phát và thu hồi không gian bộ nhớ khi được yêu cầu. 17
- 3) Quản lý tập tin Quản lý tập tin là một trong những thành phần có thể dễ thấy nhất của hệ điều hành. Máy tính có thể lưu thông tin trên nhiều loại phương tiện lưu trữ vật lý khác nhau. Băng từ, đĩa từ, đĩa quang là những phương tiện thông dụng nhất. Mỗi phương tiện này có đặc điểm và tổ chức riêng. Mỗi phương tiện được điều khiển bởi một thiết bị, như một ổ đĩa hay ổ băng từ. Các thuộc tính này bao gồm tốc độ truy xuất, dung lượng, tốc độ truyền dữ liệu và phương pháp truy xuất (tuần tự hay ngẫu nhiên). Hệ điều hành cung cấp khung nhìn logic của việc lưu trữ thông tin. Hệ điều hành trừu tượng hoá các thuộc tính vật lý của các thiết bị lưu trữ để định nghĩa một đơn vị lưu trữ logic là các tập tin. Hệ điều hành ánh xạ các tập tin trên các thiết bị lưu trữ vật lý, và truy xuất các tập tin này bằng các thiết bị lưu trữ. Tập tin là tập hợp thông tin có quan hệ với nhau và được định nghĩa bởi người khởi tạo. Thông thường, các tập tin biểu diễn chương trình và dữ liệu. Các tập tin dữ liệu có thể là chữ cái, chữ số Các tập tin có dạng bất kỳ (thí dụ, các tập tin văn bản) hay có thể được định dạng có cấu trúc (thí dụ, các trường cố định). Một tập tin chứa một chuỗi các bits, bytes, các dòng hay các mẫu tin mà ý nghĩa của nó được định nghĩa bởi người tạo. Khái niệm tập tin là một khái niệm thông dụng trong máy tính. Các tập tin được tổ chức trong các thư mục để dễ quản lý và sử dụng. Ngoài ra, khi nhiều người dùng cúng truy xuất tập tin, hệ điều hành phái kiểm soát được người dùng nào được phép truy xuất, và truy suất ở giới hạn nào (đọc, ghi, xoá, ). Hệ điều hành có nhiệm vụ thực hiện các nhiệm vụ sau trong việc quản lý hệ thống tập tin: + Tạo và xoá tập tin + Tạo và xoá thư mục + Hỗ trợ các hàm nguyên thuỷ để thao tác tập tin và thư mục + Ánh xạ các tập tin trên các thiết bị lưu trữ phụ + Sao lưu dự phòng tập tin trên các phương tiện lưu trữ ổ định 4) Quản lý hệ thống xuất/nhập Một trong những mục đích của hệ điều hành là che giấu sự khác biệt của các thiết bị phần cứng từ người dùng. Thí dụ, trong UNIX sự khác biệt của các thiết bị 18
- xuất/nhập bị che giấu từ phần chính của hệ điều hành bởi các hệ thống con xuất/nhập. Hệ thống xuất/nhập thực hiện: + Quản lý bộ nhớ chứa vùng đệm (buffering), lưu trữ (caching) và spooling (vùng chứa). + Tạo giao diện trình điều khiển thiết bị chung. + Quản lý chương trình điều khiển cho các thiết bị xác định. Chỉ chương trình điều khiển thiết bị biết sự khác biệt của các thiết bị xác định mà nó được gán 5) Quản lý hệ thống lưu trữ phụ Mục đích chính của một hệ thống máy tính là thực hiện các chương trình. Những chương trình này phải truy xuất dữ liệu nằm trong bộ nhớ chính khi tiến trình thực hiện. Vì bộ nhớ chính thường nhỏ để lưu tất cả dữ liệu và chương trình và vì dữ liệu sẽ bị xoá khi mất điện, do đó hệ thống máy tính phải cung cấp hệ thống lưu trữ phụ. Hầu hết các hệ thống máy tính hiện đại dùng các ổ đĩa như phương tiện lưu trữ phụ cho cả chương trình và dữ liệu. Hầu hết các chương trình – gồm trình biên dịch, trình dịch hợp ngữ, thủ tục sắp xếp, trình soạn thảo và trình định dạng – được lưu trên đĩa cho tới khi được nạp vào trong bộ nhớ và sau đó sử dụng đĩa trong quá trình xử lý. Do đó, quản lý tốt việc lưu trữ đĩa có vai trò quan trọng đối với một hệ thống máy tính. Hệ điều hành có nhiệm vụ thực hiện các hoạt động sau trong việc quản lý đĩa: + Quản lý không gian trống + Cấp phát lưu trữ + Lập lịch đĩa Vì lưu trữ phụ được dùng thường xuyên nên nó phải được thiết kế và sử dụng một cách hiệu quả. Tốc độ toàn bộ của các thao tác của máy tính liên quan đến tốc độ hệ thống đĩa và các giải thuật thao tác trên hệ thống đó. 6) Quản lý hệ thống mạng Hệ phân tán là tập hợp các bộ xử lý, chúng không chia sẻ bộ nhớ, các thiết bị ngoại vi hay đồng hồ. Thay vào đó mỗi bộ xử lý có riêng bộ nhớ, đồng hồ, các bộ xử lý giao tiếp với nhau thông qua các hệ thống giao tiếp như bus tốc độ cao hay mạng. Các bộ xử lý trong hệ thống phân tán khác nhau về kích thước và chức năng. Chúng 19
- có thể chứa các bộ vi xử lý, trạm làm việc, máy vi tính và các hệ thống máy tính thông thường. Các bộ xử lý trong hệ thống được nối với nhau thông qua mạng truyền thông có thể được cấu hình bằng nhiều cách khác nhau. Mạng có thể được nối kết một phần hay toàn bộ. Thiết kế mạng truyền thông phải xem xét vạch đường thông điệp và các chiến lược nối kết, các vấn đề tương tranh hay bảo mật. Hệ thống phân tán tập hợp những hệ thống vật lý riêng lẻ, có thể có kiến trúc không đồng nhất thành một hệ thống chặt chẽ, cung cấp tới người sử dụng với truy xuất tới các tài nguyên khác nhau mà hệ thống duy trì. Truy xuất tới các tài nguyên chia sẻ cho phép tăng tốc độ tính toán, chức năng, khả năng sẵn sàng của dữ liệu, độ tin cậy. Hệ điều hành thường tổng quát hoá việc truy xuất mạng như một dạng truy xuất tập tin, với những chi tiết mạng được chứa trong chương trình điều khiển thiết bị của giao tiếp mạng. Các giao thức tạo một hệ thống phân tán có thể có một ảnh hưởng to lớn trên tiện ích và tính phổ biến của hệ thống đó. Sự đổi mới của World Wide Web đã tạo ra một phương pháp truy xuất mới cho thông tin chia sẻ. Nó đã cải tiến giao thức truyền tập tin (File Transfer Protocol - FTP) và hệ thống tập tin mạng (Network File System - NFS) đã có bằng cách xoá yêu cầu cho một người dùng đăng nhập trước khi người dùng đó được phép dùng tài nguyên ở xa. Định nghĩa một giao thức mới, giao thức truyền siêu văn bản (hypertext transfer protocol - http), dùng trong giao tiếp giữa một trình phục vụ web và trình duyệt web. Trình duyệt web chỉ cần gửi yêu cầu thông tin tới một trình phục vụ web của máy ở xa, thông tin (văn bản, đồ hoạ, liên kết tới những thông tin khác) được trả về. 7) Hệ thống bảo vệ Nếu một hệ thống máy tính có nhiều người dùng và cho phép thực hiện đồng thời nhiều tiến trình, thì các tiến trình phải được bảo vệ từ các hoạt động của tiến trình khác. Với mục đích này, hệ điều hành phải tạo ra các cơ chế đảm bảo cho các tập tin, phân đoạn bộ nhớ, CPU, và các tài nguyên khác có thể được điều hành chỉ bởi các tiến trình có quyền phù hợp. Thí dụ, phần cứng phân định địa chỉ bộ nhớ sao cho một tiến trình chỉ có thể thực hiện trong không gian địa chỉ của chính nó. Bộ lập lịch đảm bảo rằng các tiến trình được cấp phát quyền sử dụng CPU và sau đó phải trả lại điều khiển. Người dùng 20
- không truy xuất tới các thanh ghi điều khiển thiết, do đó tính đúng đắn của các thiết bị ngoại vi khác nhau được bảo vệ. Bảo vệ là một cơ chế để điều khiển truy nhập của các chương trình, tiến trình hay người dùng tới tài nguyên hệ thống và được định nghĩa bởi một hệ thống máy tính. Cơ chế này phải cung cấp phương tiện để đặc tả các điều khiển được áp đặt và phương tiện thực hiện. Bảo vệ có thể cải tiến độ tin cậy bằng cách phát hiện các lỗi ẩn chứa tại các giao diện giữa các hệ thống thành phần. Sớm phát hiện các lỗi có thể ngăn chặn nguy cơ ảnh hưởng tới hệ thống con bởi một hệ thống con khác. Tài nguyên không được bảo vệ không thể ngăn chặn việc sử dụng bởi người dùng không có quyền. Hệ thống hướng bảo vệ (protection-oriented system) cung cấp một phương tiện để phân biệt giữa việc dùng có quyền và không có quyền. 8) Hệ thống thông dịch lệnh Một trong những chương trình hệ thống quan trọng nhất đối với hệ điều hành là chương trình thông dịch lệnh. Chương trình thông dịch lệnh tạo giao diện giữa người dùng và hệ điều hành. Một vài hệ điều hành chứa trình thông dịch lệnh trong nhân (kernel). Các hệ điều hành khác nhau như MS-DOS và UNIX xem trình thông dịch lệnh như một chương trình đặc biệt đang chạy khi một công việc được khởi tạo hay khi người dùng đăng nhập lần đầu tiên (trên các hệ thống phân chia thời gian). Nhiều lệnh được cung cấp tới hệ điều hành bởi các lệnh điều khiển. Khi một công việc mới được bắt đầu trong hệ thống bó, hay khi một người dùng đăng nhập vào hệ thống chia thời, thì một chương trình đọc và thông dịch các câu lệnh điều khiển được thực hiện tự động. Chương trình này còn được gọi chương trình thông dịch thẻ điều khiển (control-card interpreter) hay chương trình thông dịch dòng lệnh và thường được biết như là shell. Chức năng của nó đơn giản là: lấy câu lệnh tiếp theo và thực hiện nó. Các hệ điều hành thường khác nhau trong vùng shell, với một trình thông dịch lệnh thân thiện với người sử dụng làm cho hệ thống có thể chấp nhập nhiều thao tác hơn của người dùng. Một dạng giao diện thân thiện người dùng là hệ thống chương trình chọn lệnh bằng cửa sổ trên cơ sở chuột (mouse-based window-and-menu system) được dùng trong Macintosh và Microsoft Windows. Chuột được di chuyển 21
- tới vị trí con trỏ chuột trên hình ảnh hay biểu tượng trên màn hình biểu diễn các chương trình, tập tin, và các hàm hệ thống. Phụ thuộc vào vị trí con trỏ chuột, nhấn một nút trên chuột có thể nạp một chương trình, chọn một tập tin hay thư mục hay kéo xuống một trình đơn chứa các câu lệnh. Các shell mạnh hơn, phức tạp hơn và khó học hơn có thể được một số người dùng khác đánh giá cao vì chúng có nhiều tuỳ biến. Trong những shell này, các lệnh được đánh vào từ bàn phím được hiển thị trên màn hình hay in ra thiết bị đầu cuối, với phím enter (hay return) chỉ rằng một lệnh hoàn thành và sẵn sàng được thực hiện. Shell của MS-DOS và UNIX điều hành theo cách này. 1.2.2 Các dịch vụ của hệ điều hành Hệ điều hành cung cấp một môi trường cho việc thực hiện các chương trình. Nó cung cấp các dịch vụ xác định tới chương trình và tới người sử dụng chương trình đó. Dĩ nhiên, các dịch vụ được cung cấp khác nhau từ các hệ điều hành khác nhau nhưng chúng có thể xác định các lớp chung. Các dịch vụ hệ điều hành được cung cấp sự tiện dụng cho người lập trình để thực hiện công việc lập trình dễ dàng. - Thực hiện chương trình: hệ thống phải nạp được chương trình vào bộ nhớ và chạy chương trình đó. Chương trình phải kết thúc công việc thực hiện của nó bình thường hay hiển thị lỗi nếu kết thúc không bình thường. - Thao tác xuất/nhập: một chương trình đang chạy có thể yêu cầu xuất/nhập. Xuất/nhập này có thể liên quan tới tập tin hay thiết bị xuất/nhập. Đối với các thiết bị cụ thể, các chức năng đặc biệt có thể được mong muốn (như quay lại từ đầu một ổ băng từ, hay xoá màn hình). Đối với tính hiệu quả và tính bảo vệ, người dùng thường không thể điều khiển các thiết bị xuất/nhập trực tiếp. Do đó, hệ điều hành phải cung cấp một phương tiện để thực hiện xuất/nhập. - Thao tác hệ thống tập tin: hệ thống tập tin có sự quan tâm đặc biệt. Các chương trình cần đọc và ghi các tập tin. Chương trình cũng cần tạo và xoá tập tin bằng tên. - Giao tiếp: trong nhiều trường hợp, một tiến trình cần trao đổi thông tin với các tiến trình khác. Giao tiếp như thế có thể thực hiện bằng hai cách. Cách đầu tiên xảy ra giữa các tiến trình được thực hiện trên cùng máy tính; cách thứ hai xảy ra giữa hai tiến trình đang được thực hiện trên các máy tính khác nhau được kết nối với nhau 22
- bởi hệ thống mạng máy tính. Các giao tiếp có thể được thực hiện bằng bộ nhớ được chia sẻ, hay bằng kỹ thuật truyền thông điệp, trong đó các gói tin được di chuyển giữa các tiến trình bởi hệ điều hành. - Phát hiện lỗi: hệ điều hành liên tục yêu cầu nhận biết các lỗi có thể phát sinh. Các lỗi có thể xảy ra trong CPU và phần cứng bộ nhớ (như lỗi bộ nhớ hay lỗi về điện), trong các thiết bị xuất/nhập (như lỗi chẳn lẻ trên băng từ, lỗi nối kết mạng, hết giấy in) và trong chương trình người dùng (như tràn số học, cố gắng truy xuất một vị trí bộ nhớ không hợp lệ, dùng quá nhiều thời gian CPU). Đối với mỗi loại lỗi, hệ điều hành phải thực hiện xử lý hợp lý để đảm bảo tính toán đúng và không đổi. Ngoài ra, một tập chức năng khác của hệ điều hành tồn tại không giúp người dùng, nhưng đảm bảo các điều hành hữu hiệu của chính hệ thống. Các hệ thống với nhiều người dùng có thể đạt tính hữu hiệu bằng cách chia sẻ tài nguyên máy tính giữa các người dùng. - Cấp phát tài nguyên: khi nhiều người dùng đăng nhập vào hệ thống hay nhiều công việc đang chạy cùng lúc, tài nguyên phải được cấp tới mỗi người dùng. Nhiều loại tài nguyên khác nhau được quản lý bởi hệ điều hành. Một số tài nguyên (như chu kỳ CPU, bộ nhớ chính, lưu trữ tập tin) có mã cấp phát đặt biệt, trái lại các tài nguyên khác (như thiết bị xuất/nhập) có mã yêu cầu và giải phóng thường hơn. Thí dụ, xác định cách tốt nhất để dùng CPU, hệ điều hành có các thủ tục lập lịch CPU. Các thủ tục này xem xét tốc độ CPU, các công việc phải được thực hiện, số thanh ghi sẵn dùng và các yếu tố khác. Cũng có các thủ tục cấp phát ổ băng từ để dùng cho một công việc. Một thủ tục như thế định vị ổ băng từ chưa được dùng và đánh dấu một bảng bên trong để ghi người dùng mới của ổ băng từ. Một thủ tục khác được dùng để xoá bảng đó. Các thủ tục này cũng có thể cấp phát các máy vẽ, modem, các thiết bị ngoại vi khác. - Tính toán: chúng ta muốn lưu giữ thông tin về người dùng sử dụng bao nhiêu và loại tài nguyên máy tính nào. Các thông tin này có thể được dùng để tính toán hay đơn giản thống kê sử dụng. Thống kê sử dụng có thể là công cụ có giá trị cho người nghiên cứu muốn cấu hình lại hệ thống để cải tiến các dịch vụ tính toán. - Bảo vệ: người sở hữu thông tin được lưu trong hệ thống máy tính đa người dùng muốn kiểm soát các thông tin của mình. Khi nhiều tiến trình riêng rẽ thực hiện 23
- đồng thời, không thể cho một tiến trình can thiệp tới các tiến trình khác hay tới chính hệ điều hành. Bảo vệ đảm bảo rằng tất cả truy xuất tài nguyên của hệ thống được kiểm soát. An toàn hệ thống từ người dùng bên ngoài cũng là vấn đề quan trọng. An toàn bắt đầu với mỗi người dùng có quyền đối với hệ thống, thường bằng mật khẩu để được phép truy xuất tài nguyên. Mở rộng việc bảo vệ đối với các thiết bị xuất/nhập bên ngoài, bao gồm modem, card mạng từ những truy xuất không hợp lệ, và ghi lại các nối kết để phát hiện đột nhập vào hệ thống. Nếu hệ thống bảo vệ và bảo mật, những cảnh báo phải được thiết lập xuyên suốt. 1.2.3 Lời gọi hệ thống Lời gọi hệ thống cung cấp giao diện giữa một tiến trình và hệ điều hành. Các lời gọi này thường sẵn sàng như các chỉ thị hợp ngữ và chúng thường được liệt kê trong những tài liệu hướng dẫn sử dụng được dùng bởi những người lập trình hợp ngữ. Những hệ thống xác định cho phép lời gọi hệ thống được thực hiện trực tiếp từ một chương trình ngôn ngữ cấp cao, trong đó các lời gọi thường tương tự lời gọi hàm hay thủ tục được định nghĩa trước. Chúng có thể tạo ra một lời gọi tới một chương trình con tại thời điểm thực hiện cụ thể. Lời gọi hệ thống được gọi bằng nhiều cách khác nhau, phụ thuộc vào máy tính đang dùng. Thí dụ, để nhập dữ liệu, chúng ta có thể cần xác định tập tin hay thiết bị dùng như nguồn nhập, địa chỉ và chiều dài vùng đệm bộ nhớ mà dữ liệu nhập sẽ được đọc vào. Hình 1.5 Truyền tham số Có ba phương pháp thông dụng để truyền tham số tới hệ điều hành. Phương pháp đơn giản nhất là truyền tham số trong các thanh ghi. Trong một vài trường hợp, 24
- các tham số thường lưu trữ trong một khối hay bảng trong bộ nhớ và địa chỉ của khối được truyền như một tham số trong thanh ghi (Hình 1.5). Các tham số cũng có thể được thay thế, hay được đẩy vào trong ngăn xếp bởi chương trình, và được lấy ra khỏi ngăn xếp bởi hệ điều hành. Một vài hệ điều hành dùng phương pháp khối hay ngăn xếp vì các phương pháp này không giới hạn số lượng hay chiều dài của tham số đang được truyền. 1.2.4 Các chương trình hệ thống Các hệ điều hành hiện đại có thể coi là tập hợp của các chương trình hệ thống. Xem lại (Hình 1.1), minh họa cấu trúc phân cấp máy tính theo kiểu logic. Tại cấp thấp nhất là phần cứng. Tiếp đó là hệ điều hành, sau đó các chương trình hệ thống và cuối cùng là các chương trình ứng dụng. Các chương trình hệ thống cung cấp môi trường thuận lợi cho việc phát triển và thực hiện chương trình. Một số chương trình hệ thống tạo ra các giao diện người dùng đơn giản cho các lời gọi hệ thống; các hệ thống còn lại được xem xét phức tạp hơn. Chúng có thể được chia thành các loại sau: - Quản lý tập tin: các chương trình tạo, xóa, chép, đổi tên, in, kết xuất, liệt kê, và các thao tác tập tin thư mục thông thường. - Thông tin trạng thái: một vài chương trình đơn giản yêu cầu hệ thống ngày, giờ, lượng bộ nhớ hay đĩa sẵn dùng, số lượng người dùng, hay thông tin trạng thái tương tự. Sau đó, thông tin được định dạng và được in tới thiết bị đầu cuối hay thiết bị xuất khác hoặc tập tin. - Thay đổi tập tin: nhiều trình soạn thảo văn bản có thể sẵn dùng để tạo và thay đổi nội dung của tập tin được lưu trên đĩa hay băng từ. - Hỗ trợ ngôn ngữ lập trình: trình biên dịch, trình hợp ngữ và trình thông dịch cho các ngôn ngữ lập trình thông dụng (như C, C++, Java, Visual Basic và PERL) thường được cung cấp tới người dùng với hệ điều hành. - Nạp và thực hiện chương trình: một khi chương trình được tập hợp hay được biên dịch, nó phải được nạp vào bộ nhớ để được thực hiện. Hệ thống có thể cung cấp bộ nạp tuyệt đối, bộ nạp có thể tái định vị, bộ soạn thảo liên kết và bộ nạp phủ lắp. Các hệ thống gỡ rối cho các ngôn ngữ cấp cao hay ngôn ngữ máy cũng được yêu cầu. 25
- - Giao tiếp: các chương trình này cung cấp cơ chế tạo các nối kết ảo giữa các tiến trình, người dùng, các hệ thống máy tính khác. Chúng cho phép người dùng gửi các thông điệp tới màn hình của người dùng khác, hiển thị các trang web, gửi thư điện tử, đăng nhập từ xa hay để chuyển các tập tin từ máy tính này tới máy tính khác. Nhiều hệ điều hành được cung cấp với các chương trình giải quyết các vấn đề giao tiếp thông thường hay thực hiện các thao tác phổ biến. Những chương trình như thế gồm các trình duyệt Web, bộ xử lý văn bản và bộ định dạng văn bản, hệ cơ sở dữ liệu, trình biên dịch, các gói phần mềm đồ họa và phân tích thống kê, trò chơi, Những chương trình này được gọi là các tiện ích hệ thống hay chương trình ứng dụng. Hầu hết người dùng nhìn hệ điều hành như các chương trình hệ thống hơn các lời gọi hệ thống thực sự. Khi sử dụng máy tính PC chạy hệ điều hành Microsoft Windows, chúng ta có thể thấy một trình thông dịch dòng lệnh MS-DOS hay giao diện cửa sổ và trình đơn đồ họa. Cả hai sử dụng cùng một tập lời gọi hệ thống như lời gọi hệ thống trông rất khác và hoạt động trong các cách khác nhau. Do đó, tầm nhìn của chúng ta về thực chất có thể bị tách rời với cấu trúc hệ thống thực sự. 1.2.5 Cấu trúc hệ thống Một hệ thống lớn và phức tạp như một hệ điều hành hiện đại phải được xây dựng để nó thực hiện chức năng hợp lý và được hiệu chỉnh dễ dàng. Thông thường, người ta chia các công việc mà hệ điều hành cấn thực hiện ra thành các thành phần nhỏ hơn, có chức năng tương đối độc lập và được gọi là các khối. Mỗi khối này phải có chức năng, đầu vào, đầu ra rất cụ thể. Trong phần này chúng ta sẽ thảo luận về cách thức mà các thành phần được nối kết với nhau. 1) Cấu trúc đơn giản Application program Resident system program MS_DOS device drivers ROM BIOS device drivers Hình 1.6 Cấu trúc phân tầng của MS-DOS 26
- Nhiều hệ điều hành thương mại không có kiến trúc rõ ràng. Thông thường các hệ điều hành như thế được bắt đầu như các hệ thống nhỏ, đơn giản và có giới hạn. Sau đó chúng bổ xung thêm tính năng và lớn hơn giới hạn ban đầu của chúng. MS-DOS là một thí dụ cho hệ thống dạng này. Ban đầu, nó được thiết kế và thực hiện bởi một vài người mà chính họ không tưởng rằng MS-DOS sẽ trở nên phổ biến trên toàn thế giới. Nó được viết để cung cấp các khả năng nhiều nhất trong không gian ít nhất (vì bị giới hạn bởi phần cứng mà nó đang chạy) vì nó không được phân chia thành các modules một cách rõ ràng. UNIX là một hệ điều hành khác mà ban đầu nó bị giới hạn bởi chức năng phần cứng. Nó chứa hai phần có thể tách rời nhau: nhân và các chương trình hệ thống. Nhân lại được chia thành một loạt các giao diện và trình điều khiển thiết bị mà chúng được thêm vào và mở rộng trong một thời gian dài khi UNIX được cải tiến. Hệ điều hành UNIX ban đầu được phân tầng như (Hình 1.7). Ở giữa giao diện lời gọi hệ thống và phần cứng vật lý là nhân. Nhân cung cấp hệ thống tập tin, bộ lập lịch CPU, quản lý bộ nhớ và các chức năng khác của hệ điều hành thông qua lời gọi hệ thống. Có rất nhiều chức năng được nối kết trong cấp thứ nhất. Điều này làm cho UNIX khó có thể nâng cấp khi những thay đổi trong một phần ảnh hưởng bất lợi cho những phần khác. (the users) Shells and commands compilers and interpreters system libraries System- call interface to the kermel Signals terminal File system CPU scheduling handing charater I/O swapping block I/O page replacement system terminal system demand paging drivers disk and tape drivers virtual memory Kernel interface to the hardware Terminal controllers Device controllers Memory controllers terminals disks and tapes physical memory Hình 1.7 Cấu trúc hệ thống của UNIX 27
- Lời gọi hệ thống định nghĩa giao diện lập trình ứng dụng (API-Application Programming Interface) cho UNIX; tập hợp các chương trình hệ thống thường sẵn dùng định nghĩa giao diện người dùng. Người lập trình và giao diện người dùng định nghĩa trạng thái mà nhân phải hỗ trợ. Những phiên bản mới của UNIX được thiết kế để dùng phần cứng tiên tiến hơn, được cung cấp sự hỗ trợ phần cứng hợp lý, các hệ điều hành có thể được chia thành nhiều phần nhỏ hơn và phù hợp hơn so với các hệ thống MS-DOS và UNIX ban đầu. 2) Phương pháp phân tầng Việc phân chia từng phần của một hệ thống có thể được thực hiện bằng nhiều cách. Một trong những phương pháp này là thực hiện tiếp cận phân tầng. Trong tiếp cận này hệ điều hành được chia thành nhiều tầng (hay cấp), mỗi tầng được xây dựng trên đỉnh của tầng dưới nó. Tầng cuối cùng (tầng 0) là phần cứng; tầng cao nhất (tầng N) là giao diện người dùng. Một tầng hệ điều hành là sự cài đặt của một đối tượng trừu tượng. Đối tượng trừu tượng này là sự bao gói dữ liệu và các điều hành có thể thao tác dữ liệu đó. Một tầng hệ điều hành điển hình – tầng M - được mô tả trong (Hình 1.4). Nó chứa các cấu trúc dữ liệu và tập hợp các thủ tục có thể được gọi bởi các tầng cấp cao hơn. Sau đó, tầng M có thể gọi các thao tác trên tầng cấp thấp hơn. layer M New : operationsns : Hidden : layer M- 1 operation : s Existing : operation : s Hình 1.8 Một tầng hệ điều hành Lợi ích chủ yếu của tiếp cận phân tầng là tính module. Các tầng được chọn dựa trên cơ sở tầng trên sử dụng chức năng (hay các điều hành) và các dịch vụ chỉ của 28
- tầng cấp dưới nó. Tiếp cận này đơn giản hóa việc gỡ rối và kiểm tra hệ thống. Tầng đầu tiên có thể được gỡ rối mà không có bất cứ sự quan tâm nào cho phần còn lại của hệ thống. Bởi vì theo định nghĩa, nó chỉ sử dụng phần cứng cơ bản để cài đặt các chức năng của nó. Một khi tầng đầu tiên được gỡ rối, chức năng sửa lỗi của nó có thể được đảm đương trong khi tầng thứ hai được gỡ rối, Nếu một lỗi được tìm thấy trong khi gỡ rối cho một tầng xác định, lỗi phải được nằm trên tầng đó vì các tầng bên dưới đã được gỡ rối rồi. Do đó, thiết kế và cài đặt hệ thống được đơn giản hóa khi hệ thống được phân chia thành nhiều tầng. Mỗi tầng được cài đặt chỉ với các thao tác được cung cấp bởi các tầng bên dưới. Một tầng không cần biết các thao tác được cài đặt như thế nào; nó chỉ cần biết các thao tác đó làm gì. Do đó, mỗi tầng che giấu sự tồn tại của cấu trúc dữ liệu, thao tác và phần cứng từ các tầng cấp cao hơn. Khó khăn chính của tiếp cận phân tầng liên quan tới việc định nghĩa chính xác các tầng vì một tầng chỉ có thể sử dụng các tầng bên dưới nó. Thí dụ, trình điều khiển thiết bị cho không gian đĩa được dùng bởi các giải thuật bộ nhớ ảo phải nằm ở tại cấp thấp hơn trình điều khiển thiết bị của các thủ tục quản lý bộ nhớ vì quản lý bộ nhớ yêu cầu khả năng sử dụng không gian đĩa. Các yêu cầu có thể không thật sự rõ ràng. Thường thì các trình điều khiển lưu trữ dự phòng nằm trên bộ lập lịch CPU vì trình điều khiển cần phải chờ nhập/xuất và CPU có thể được lập lịch lại trong thời gian này. Tuy nhiên, trên hệ thống lớn, bộ lập lịch có thể có nhiều thông tin hơn về tất cả tiến trình đang hoạt động hơn là có thể đặt vừa trong bộ nhớ. Do đó, thông tin này có thể cần được hoán vị vào và ra bộ nhớ, yêu cầu thủ tục trình điều khiển lưu trữ dự phòng nằm bên dưới bộ lập lịch CPU. Vấn đề cuối cùng với các cài đặt phân tầng là chúng có khuynh hướng ít hiệu quả hơn các loại khác. Thí dụ, khi chương trình người dùng thực hiện thao tác nhập/xuất, nó thực hiện một lời gọi hệ thống. Lời gọi hệ thống này được đẩy tới tầng nhập/xuất, nó yêu cầu tầng quản lý bộ nhớ, sau đó gọi tầng lập lịch CPU, sau đó được truyền tới phần cứng. Tại mỗi tầng, các tham số có thể được hiệu chỉnh, dữ liệu có thể được truyền, Mỗi tầng thêm chi phí cho lời gọi hệ thống; kết quả thực sự là lời gọi hệ thống mất thời gian lâu hơn khi chúng thực hiện trên hệ thống không phân tầng. 29
- application application application Application- programming interface API extension subsystem subsystem subsystem System - Memory management kernel - Task dispatching - Device management device driver device driver device driver Hình 1.9 Cấu trúc phân tầng của OS/2 Những giới hạn này gây một phản ứng nhỏ chống lại việc phân tầng trong những năm gần đây. Rất ít các tầng với nhiều chức năng được thiết kế, cung cấp nhiều lợi điểm của mã được module trong khi tránh những vấn đề khó khăn của định nghĩa và giao tiếp tầng. Thí dụ, OS/2 bổ sung thêm tính năng đa tác vụ và điều hành hai chế độ cùng một số đặc điểm mới. Vì tính phức tạp được bổ sung và phần cứng mạnh hơn mà OS/2 được thiết kế, hệ thống được cài đặt trong dạng phân tầng. 3) Vi nhân (Microkernels) Khi hệ điều hành UNIX được mở rộng, nhân trở nên lớn và khó quản lý. Vào giữa những năm 1980, các nhà nghiên cứu tại đại học Carnegie Mellon phát triển một hệ điều hành được gọi là Match mà module hóa nhân dùng tiếp cận vi nhân (micro kernel). Phương pháp này xác định kiến trúc của hệ điều hành bằng cách xóa tất cả thành phần không quan trọng từ nhân và cài chúng như các chương trình người dùng và hệ thống. Kết quả này làm cho nhân nhỏ hơn. Có tranh cãi liên quan đến việc quyết định dịch vụ nào nên để lại trong nhân và dịch vụ nào nên được cài đặt trong không gian người dùng. Tuy nhiên, thường thì các vi nhân điển cung cấp tiến trình và quản lý bộ nhớ tối thiểu ngoài phương tiện giao tiếp. Chức năng chính của vi nhân là cung cấp tiện nghi giao tiếp giữa chương trình khách hàng và các dịch vụ khác mà chúng đang chạy trong không gian người dùng. Giao tiếp được cung cấp bằng truyền thông điệp. Thí dụ, nếu chương trình khách hàng muốn truy xuất một tập tin, nó phải giao tiếp với trình phục vụ tập tin (file 30
- server). Chương trình người dùng và dịch vụ không bao giờ giao tiếp trực tiếp. Đúng hơn là chúng giao tiếp gián tiếp bằng cách truyền thông điệp với vi nhân. Thuận lợi của tiếp cận vi nhân là dễ dàng mở rộng hệ điều hành. Tất cả dịch vụ mới được thêm tới không gian người dùng và do đó không yêu cầu phải hiệu chỉnh nhân. Kết quả là hệ điều hành dễ dàng hơn để chuyển đổi từ thiết kế phần cứng này sang thiết kế phần cứng khác. Vi nhân cũng cung cấp khả năng an toàn và tin cậy hơn vì hầu hết các dịch vụ đang chạy của người dùng. Nếu một dịch vụ bị lỗi, phần còn lại của hệ điều hành vẫn không bị ảnh hưởng. Một số hệ điều hành hiện đại dùng tiếp cận vi nhân. Tru64 UNIX (Digital UNIX trước đây) cung cấp giao diện UNIX tới người dùng, nhưng nó được cài đặt với nhân Mach. Nhân Mach ánh xạ các lời gọi hệ thống vào các thông điệp tới các dịch vụ cấp người dùng tương ứng. Hệ điều hành Apple MacOS Server được dựa trên cơ sở nhân Mach. QNX là hệ điều hành thời thực cũng dựa trên cơ sở thiết kế vi nhân. Vi nhân QNX cung cấp các dịch vụ cho việc truyền thông điệp, lập lịch tiến trình. Nó cũng quản lý giao tiếp mạng cấp thấp và các ngắt phần cứng. Các dịch vụ khác trong QNX được cung cấp bởi các tiến trình chuẩn chạy bên ngoài nhân trong chế độ người dùng. Windows NT dùng một cấu trúc tổng hợp. Windows NT được thiết kế để chạy các ứng dụng khác nhau, gồm Win32 (ứng dụng thuần Windows), OS/2, và POSIX (Portable Operating System Interface for uniX). Nó cung cấp một server chạy trong không gian người dùng cho mỗi loại ứng dụng. Các chương trình khách hàng cho mỗi loại ứng dụng chạy trong không gian người dùng. Nhân điều phối việc truyền thông điệp giữa các ứng dụng khách hàng và server ứng dụng. Cấu trúc client-server của Windows NT được mô tả trong (Hình 1.10) Win32 OS/2 OS/2 applicatio applicatio applicatio n n n Win32 OS/2 POSIX server server application kernel Hình 1.10 Cấu trúc client-server của Windows NT 31
- 4) Máy ảo Về mặt khái niệm, một hệ thống máy tính được cấu thành từ các tầng. Phần cứng là cấp thấp nhất trong tất cả hệ thống như thế. Nhân chạy tại cấp kế tiếp dùng các chỉ thị phần cứng để tạo một tập lời gọi hệ thống cho việc sử dụng các tầng bên ngoài. Do đó, các chương trình hệ thống trên nhân có thể dùng các lời gọi hệ thống hay các chỉ thị phần cứng. Trong nhiều trường hợp, các chương trình này không có sự khác biệt giữa hai cách thực hiện. Do đó, mặc dù chúng được truy xuất khác nhau, nhưng cả hai cung cấp chức năng mà chương trình có thể dùng để tạo thậm chí nhiều chức năng tiên tiến hơn. Sau đó, các chương trình hệ thống xem phần cứng và các lời gọi hệ thống như chúng đang ở cùng một cấp. Một vài hệ thống thực hiện cơ chế này một cách chi tiết hơn bằng cách cho phép các chương trình hệ thống được gọi dễ dàng bởi các chương trình ứng dụng. Trước đó, mặc dù các chương trình hệ thống ở tại cấp cao hơn các thủ tục khác, nhưng các chương trình ứng dụng có thể hiển thị mọi thứ dưới chúng trong cấu trúc phân cấp như là một phần của chính máy đó. Tiếp cận phân tầng này được đưa đến một kết luận luận lý trong khái niệm máy ảo (virtual machine). Một hệ điều hành máy ảo cho các hệ thống IBM là một thí dụ điển hình nhất về khái niệm máy ảo vì IBM tiên phong thực hiện trong lĩnh vực này. Bằng cách sử dụng bộ lập lịch CPU và kỹ thuật bộ nhớ ảo, một hệ điều hành có thể tạo một hình ảnh mà một tiến trình có bộ xử lý của chính nó với bộ nhớ (ảo) của chính nó. Dĩ nhiên, thường thì một tiến trình có các đặc điểm khác nhau, như các lời gọi hệ thống và hệ thống tập tin, mà không được cung cấp bởi phần cứng. Thêm vào đó, tiếp cận máy ảo không cung cấp bất kỳ chức năng bổ sung nào; đúng hơn là cung cấp một giao diện giống hệt như phần cứng ở bên dưới. Mỗi tiến trình được cung cấp với một bản sao (ảo) của máy tính bên dưới (Hình 1.11). Một khó khăn chính với tiếp cận máy ảo liên quan đến hệ thống đĩa. Giả sử rằng máy vật lý có ba ổ đĩa nhưng muốn hỗ trợ bảy máy ảo. Rõ ràng, nó không thể cấp phát một ổ đĩa tới mỗi máy ảo. Nhớ rằng chính phần mềm máy ảo sẽ cần không gian đĩa liên tục để cung cấp bộ nhớ ảo. Giải pháp này cung cấp đĩa ảo, mà nó đúng trong tất cả khía cạnh ngoại trừ kích thước-được thuật ngữ hóa đĩa nhỏ (minidisks) trong hệ điều hành máy ảo của IBM. Hệ thống cài đặt nhiều đĩa nhỏ bằng cách cấp 32
- phát nhiều rảnh ghi trên đĩa vật lý như là các đĩa nhỏ khi cần. Hiển nhiên, tổng kích thước của tất cả đĩa nhỏ là nhỏ hơn kích thước của không gian đĩa vật lý sẵn có. processes processes processes processes kernel kernel kernel Programming interface VM1 VM2 VM3 kernel Virtual machine implementation hardware hardware Hình 1.11 Các mô hình hệ thống. (a) Máy không ảo. (b) máy ảo Do đó, người dùng được cho máy ảo của chính họ. Sau đó, họ có thể chạy bất kỳ hệ điều hành hay gói phần mềm nào sẵn dùng trên phần cứng bên dưới. Đối với hệ thống IBM VM, một người dùng thường chạy CMS - một hệ điều hành giao tiếp đơn người dùng. Phần mềm máy ảo được quan tâm với đa máy ảo đa chương trên một máy vật lý nhưng không cần xem xét bất cứ phần mềm hỗ trợ người dùng. Việc sắp xếp này có thể cung cấp một sự phân chia hữu ích thành hai phần nhỏ hơn của vấn đề thiết kế một hệ thống giao tiếp đa người dùng. 1.2.6 Cài đặt và thiết kế hệ thống Mặc dù khái niệm máy ảo là hữu ích nhưng rất khó cài đặt. Nhiều công việc được yêu cầu cung cấp một bản sao chính xác của máy bên dưới. Máy bên dưới có hai chế độ: chế độ người dùng và chế độ kiểm soát. Phần mềm máy ảo có thể chạy trong chế độ kiểm soát vì nó là hệ điều hành. Chính máy ảo có thể thực hiện chỉ trong chế độ người dùng. Tuy nhiên, chỉ khi máy vật lý có hai chế độ thì nó mới là máy ảo. Do đó, chúng ta phải có một chế độ người dùng ảo và một chế độ kiểm soát ảo. Cả hai đều chạy trong chế độ người dùng vật lý. Các hoạt động đó gây ra sự chuyển từ chế độ người dùng tới chế độ kiểm soát trên một máy thật (như lời gọi hệ thống hay 33
- cố gắng thực hiện một chỉ thị được cấp quyền) cũng phải gây ra sự chuyển đổi từ chế độ người dùng ảo tới chế độ kiểm soát ảo trên một máy ảo. Có hai ưu điểm chính trong việc sử dụng máy ảo. Thứ nhất, bằng cách bảo vệ hoàn toàn các tài nguyên hệ thống, máy ảo cung cấp mức độ bảo mật cao. Thứ hai, máy ảo cho phép phát triển hệ thống được thực hiện mà không cần phá vỡ hoạt động hệ thống thông thường. Mỗi máy ảo hoàn toàn bị cô lập từ các máy ảo khác, vì thế chúng ta không gặp phải bất kỳ vấn đề bảo mật nào như tài nguyên hệ thống khác hoàn toàn được bảo vệ. Thí dụ, các ứng dụng không được tin cậy được tải về từ Internet có thể được chạy trong một máy ảo riêng. Một bất lợi của môi trường này là không có sự chia sẻ tài nguyên trực tiếp. Hai tiếp cận cung cấp sự chia sẻ được cài đặt. Thứ nhất, có thể chia sẻ một đĩa nhỏ. Cơ chế này được làm mẫu sau một đĩa được chia sẻ vật lý. Thứ hai, có thể định nghĩa một mạng của các máy ảo, mỗi máy ảo có thể gửi thông tin qua các mạng giao tiếp này nhưng nó được cài đặt bằng phần mềm. Những hệ thống máy ảo như thế là một phương tiện truyền thông hữu hiệu cho việc nghiên cứu và phát triển hệ điều hành. Thông thường, thay đổi một hệ điều hành là một tác vụ khó. Vì các hệ điều hành là các chương trình lớn và phức tạp, sự thay đổi trên một phần này có thể gây một lỗi khó hiểu trong những phần khác. Sức mạnh của hệ điều hành làm cho trường hợp này là cực kỳ nguy hiểm. Vì hệ điều hành thực hiện trong chế độ kiểm soát, một thay đổi sai trong một con trỏ có thể gây lỗi và có thể phá hủy toàn hệ thống tập tin. Do đó, cần phải kiểm tra tất cả thay đổi của hệ điều hành một cách cẩn thận. Tuy nhiên, hệ điều hành chạy trên máy và điều khiển hoàn toàn máy đó. Do đó, hệ thống hiện hành phải bị dừng và ngừng việc sử dụng trong khi những thay đổi được thực hiện và kiểm tra. Thời điểm này thường được gọi là thời gian phát triển hệ thống. Vì nó làm cho hệ thống không sẵn dùng đối với người sử dụng nên thời gian phát triển hệ thống thường được lập thời biểu vào buổi tối hay cuối tuần, khi tải hệ thấp. Một hệ thống máy ảo có thể loại trừ nhiều vấn đề này. Người lập trình hệ thống được cung cấp chính máy ảo của họ, và phát triển hệ thống được thực hiện trên máy ảo thay vì trên máy vật lý thật sự. Một hệ điều hành thông thường ít khi bị phá 34
- vỡ vì phát triển hệ thống. Mặc dù những thuận lợi này, nhưng rất ít cải tiến trên kỹ thuật này được thực hiện gần đây. Câu hỏi và bài tập chương 1 1. Trình bày khái niệm về tài nguyên hệ thống, cho ví dụ minh hoạ 2. Nêu các chức năng cơ bản của hệ điều hành 3. Trình bày mối quan hệ giữa hệ điều hành và các thành phần trong hệ thống, từ đó nêu khái niệm hệ điều hành 4. Phân biệt hệ điều hành đơn nhiệm và đa nhiệm, cho ví dụ thông qua hệ điều hành DOS và Windows 5. Thông qua các hệ điều hành đã biết, cho ví dụ minh hoạ để làm rõ các tính chất của hệ điều hành 6. So sánh cơ chế bảo vệ của hệ điều hành Windows 9x, Windows 2000 và Windows XP 7. Nêu các chương trình hệ thống, chương trình ứng dụng trong hệ điều hành DOS và Windows 8. Nêu các thành phần của hệ điều hành, lấy ví dụ minh hoạ từ các hệ điều hành cụ thể 9. Lời gọi hệ thống là gì, các cách truyền tham số cho lời gọi hệ thống 10. Máy ảo là gì? Vì sao cần máy ảo? Cho biết các máy ảo đã được cài đặt và sử dụng trong thực tế 35
- Chương 2: QUẢN LÝ TIẾN TRÌNH 2.1 Tiến tình Hệ thống máy tính đơn nhiệm chỉ cho phép một chương trình được thực hiện tại một thời điểm. Chương trình này có toàn quyền điều khiển hệ thống và có truy xuất tới tất cả tài nguyên của hệ thống. Hệ thống đa nhiệm hay sử dụng trong máy tính hiện nay cho phép nhiều chương trình được nạp vào bộ nhớ và được thực hiện đồng thời, do đó cần điều khiển phức tạp hơn và phân chia nhiều hơn giữa các tiến trình. Một hệ điều hành đa nhiệm sẽ phải thực hiện đồng thời nhiều chương trình của người sử, đồng thời phải quan tâm đến các thao tác của người sử dụng với hệ thống như vào ra dữ liệu, trao đổi dữ liệu giữa các tiến trình, Do đó, một hệ thống đa nhiệm sẽ chứa tập hợp các tiến trình: tiến trình hệ điều hành thực hiện mã hệ thống, tiến trình người dùng thực hiện mã người dùng. Tất cả tiến trình này đều có thể được phối hợp thực hiện đồng thời bằng một hay nhiều CPU. Bằng cách chuyển đổi CPU giữa các tiến trình, hệ điều hành đa nhiệm có thể làm cho máy tính hoạt động với hiệu suất cao hơn. 2.1.1 Khái niệm tiến trình Trong hệ điều hành đa nhiệm, một người dùng có thể chạy nhiều chương trình tại một thời điểm: bộ xử lý văn bản, trình duyệt web, e-mail, Thậm chí nếu người dùng chỉ thực hiện một tiến trình tại một thời điểm, thì hệ điều hành đa nhiệm cũng cần các tiến trình hệ thống hỗ trợ hoạt động bên trong như quản lý bộ nhớ, quản lý vào ra dữ liệu, 1) Tiến trình Một tiến trình là một chương trình đang thực hiện. Một tiến trình không chỉ là chương trình, mà còn bao gồm hoạt động hiện tại như giá trị của bộ đếm chương trình, nội dung các thanh ghi của bộ xử lý, ngăn xếp tiến trình để chứa dữ liệu tạm thời trong tiến trình thực hiện tiến trình (như các tham số phương thức, các địa chỉ trả về, các biến cục bộ) và phần dữ liệu chứa các biến toàn cục. Một chương trình là một thực thể thụ động, như nội dung của các tập tin được lưu trên đĩa, trái lại một tiến trình là một thực thể chủ động, với một bộ đếm chương trình xác định chỉ thị lệnh tiếp theo sẽ thực hiện và tập hợp tài nguyên có liên quan. 36
- Mặc dù hai tiến trình có thể được liên kết với cùng chương trình nhưng chúng được chứa hai thứ tự thực hiện riêng rẽ. Thí dụ, nhiều người dùng có thể đang chạy các bản sao của chương trình gửi nhận thư, hay cùng người dùng có thể nạp lên nhiều bản sao của một chương trình soạn thảo văn bản. Mỗi bản sao của chúng là một tiến trình riêng và mặc dù các phần văn bản là giống nhau, các phần dữ liệu khác nhau. Ngoài ra, một tiến trình có thể tạo ra nhiều tiến trình khác khi nó thực hiện. 2) Trạng thái tiến trình Khi một tiến trình thực hiện, nó thay đổi trạng thái. Trạng thái của tiến trình được định nghĩa bởi các hoạt động hiện hành của tiến trình đó. Mỗi tiến trình có thể ở một trong những trạng thái sau: - Mới (new): tiến trình đang được tạo ra - Đang chạy (running): các chỉ thị đang được thực hiện - Chờ (waiting): tiến trình đang chờ sự kiện xảy ra (như hoàn thành việc nhập/xuất hay nhận tín hiệu) - Sẵn sàng (ready): tiến trình đang chờ được nhận một bộ xử lý. - Kết thúc (terminated): tiến trình hoàn thành việc thực hiện terminated new admit dispatch exit ready running interrupt I/O or event I/O or event completion wait waiting Hình 2.1 Lưu đồ trạng thái tiến trình 3) Khối điều khiển tiến trình Mỗi tiến trình được quản lý trong hệ điều hành bởi một khối điều khiển tiến trình (Process Control Block - PCB). Một PCB được hiển thị trong (Hình 2.2). Nó chứa nhiều trường thông tin gắn liền với một tiến trình cụ thể, gồm: 37
- Hình 2.2 Khối điều khiển tiến trình - Con trỏ tiến trình (pointer): chứa con trỏ để liên kết các PCB thành danh sách. - Trạng thái tiến trình (process state): trạng thái có thể là mới, sẵn sàng, đang chạy, chờ đợi, kết thúc, - Bộ đếm chương trình (program counter): bộ đếm hiển thị địa chỉ của chỉ thị kế tiếp sẽ được thực hiện cho tiến trình này. - Các thanh ghi (registers): các thanh ghi khác nhau về số lượng và loại, phụ thuộc vào kiến trúc máy tính. Chúng gồm các bộ tổng (accumulators), các thanh ghi chỉ mục (index), các con trỏ ngăn xếp, các thanh ghi đa năng (general-purpose registers), cùng với thông tin mã điều kiện (condition-code information). Cùng với bộ đếm chương trình, thông tin trạng thái này phải được lưu khi xuất hiện một ngắt, cho phép tiến trình lưu vị trí lệnh sẽ thực hiện tiếp (Hình 2.3). - Thông tin lập lịch CPU (CPU scheduling information): thông tin gồm độ ưu tiên của tiến trình, các con trỏ chỉ tới các hàng đợi lập lịch, và các tham số lập lịch khác. - Thông tin quản lý bộ nhớ (Memory management information): thông tin này có thể gồm những thông tin như giá trị của các thanh ghi cơ sở (base) và thanh ghi giới hạn (limit), các bảng trang hay các bảng phân đoạn, phụ thuộc hệ thống bộ nhớ được tổ chức bởi hệ điều hành. 38
- - Thông tin tính toán (accounting information): thông tin này gồm lượng CPU và thời gian thực được dùng, công việc hay số tiến trình, - Thông tin trạng thái nhập/xuất (I/O status information): thông tin này gồm danh sách của thiết bị nhập/xuất được cấp phát tiến trình này, một danh sách các tập tin đang mở, PCB đơn giản phục vụ như kho chứa cho các thông tin khác nhau khi chuyển đổi CPU từ tiến trình này sang tiến trình khác. Hình 2.3 Lưu đồ chuyển CPU từ tiến trình này sang tiến trình khác 2.1.2 Lập lịch tiến trình Mục tiêu của việc đa chương là có nhiều tiến trình thực hiện tại mọtt thời điểm để tận dụng tối đa hiệu suất sử dụng CPU. Mục tiêu của lập lịch là chuyển CPU giữa các tiến trình thường xuyên để người dùng có thể giao tiếp với mỗi chương trình trong khi các chương trình đang chạy. Một hệ thống có 1 bộ vi xử lý chỉ có thể chạy một tiến trình tại một thời điểm, nếu nhiều hơn một tiến trình tồn tại, các tiến trình còn lại phải chờ cho tới khi CPU rỗi mới có thể được thực hiện, do đó cần lập lịch cho CPU. 39
- 1) Hàng đợi lập lịch Khi các tiến trình được đưa vào hệ thống, chúng được đặt vào hàng đợi. Hàng đợi chứa tất cả tiến trình trong hệ thống. Các tiến trình đang nằm trong bộ nhớ chính sẵn sàng và chờ để thực hiện được giữ trong một danh sách được gọi là hàng đợi sẵn sàng. Hàng đợi này thường được lưu như một danh sách liên kết. Đầu của hàng đợi sẵn sàng chứa hai con trỏ: một chỉ đến PCB đầu tiên và một chỉ tới PCB cuối cùng trong danh sách. Chúng ta bổ sung thêm trong mỗi PCB một trường con trỏ chỉ tới PCB kế tiếp trong hàng đợi sẵn sàng. Hệ điều hành cũng có các hàng đợi khác. Khi một tiến trình được cấp phát CPU, nó thực hiện trong một khoảng thời gian và cuối cùng kết thúc, được ngắt, hay chờ một sự kiện xác định xảy ra như hoàn thành một yêu cầu nhập/xuất. Trong trường hợp có yêu cầu nhập/xuất, một yêu cầu có thể là ổ băng từ hay một ổ đĩa từ. Vì hệ thống có nhiều tiến trình, đĩa từ có thể bận với yêu cầu nhập/xuất của các tiến trình khác. Do đó, tiến trình phải chờ đĩa từ. Danh sách tiến trình chờ một thiết bị nhập/xuất cụ thể được gọi là hàng đợi thiết bị. Mỗi thiết bị có hàng đợi của nó (Hình 2.4) Hình 2.4 Hàng đợi sẵn sàng và các hàng đợi nhập/xuất khác nhau 40
- Một biểu diễn chung của lập lịch tiến trình là một lưu đồ hàng đợi, như (Hình 2.5). Mỗi hình chữ nhật hiện diện một hàng đợi. Hai loại hàng đợi được hiện diện: hàng đợi sẵn sàng và tập các hàng đợi thiết bị, vòng tròn hiện diện tài nguyên phục vụ hàng đợi, các mũi tên hiển thị dòng các tiến trình trong hệ thống. Một tíên trình mới khởi tạo được đặt vào hàng đợi. Nó chờ trong hàng đợi sẵn sàng cho tới khi nó được chọn thực hiện. Khi tiến trình được cấp phát CPU và đang thực hiện, một trong nhiều sự kiện có thể xảy ra: - Tiến trình có thể phát ra một yêu cầu nhập/xuất và sau đó được đặt vào trong hàng đợi nhập/xuất. - Tiến trình có thể tạo một tiến trình con và chờ cho tiến trình con kết thúc - Khi một ngắt xảy ra, tiến trình có thể bị buộc trả lại CPU và được đặt trở lại trong hàng đợi sẵn sàng. Khi thực hiện xong nhập/xuất hoặc tiến trình của mình con kết thúc, tiến trình chuyển từ trạng thái chờ tới trạng thái sẵn sàng và sau đó được đặt trở lại vào hàng đợi sẵn sàng. Tiến trình sẽ tiếp tục chu kỳ này cho tới khi nó kết thúc. Tại thời điểm kết thúc, tiến trình sẽ bị xoá từ tất cả hàng đợi. Sau đó, PCB và tài nguyên của nó được thu hồi. Hình 2.5 Biểu diễn lưu đồ hàng đợi của lập lịch tiến trình 41
- 2) Bộ lập lịch Một tiến trình chuyển đổi giữa hai hàng đợi lập lịch khác nhau suốt thời gian tồn tại của tiến trình. Hệ điều hành phải chọn, cho mục đích lập lịch, các tiến trình từ các hàng đợi này. Tiến trình chọn lựa này được thực hiện bởi bộ lập lịch hợp lý. Trong hệ thống bó, thông thường có nhiều tiến trình xếp hành đợi thực hiện. Các tiến trình này được lưu trên các thiết bị lưu trữ (như đĩa cứng), nơi chúng được lưu giữ cho tới khi được thực hiện sau đó. Bộ lập lịch dài hạn (long-term scheduler) hay bộ lập lịch công việc (job scheduler), sẽ thực hiện việc chọn các tiến trình từ vùng đệm và nạp chúng vào bộ nhớ để thực hiện. Bộ lập lịch ngắn hạn (short-term scheduler) hay bộ lập lịch cho CPU, sẽ chọn một tiến trình từ các tiến trình sẵn sàng thực hiện và cấp phát CPU cho tiến trình đó. Sự khác biệt chủ yếu giữa hai bộ lập lịch là tính thường xuyên của việc thực hiện. Bộ lập lịch CPU phải thường xuyên chọn một tiến trình mới cho CPU. Một tiến trình có thể thực hiện trong thời gian chỉ một vài mili giây trước khi chờ yêu cầu nhập/xuất. Bộ lập lịch CPU thường thực hiện ít nhất một lần mỗi 100 mili giây. Vì thời gian lựa chọn rất ngắn nên bộ lập lịch phải thực hiện nhanh. Nếu nó mất 10 mili giây để quyết định thực hiện một tiến trình 100 mili giây thì 10/(100+10) = 9% thời gian của CPU đang được dùng (hay bị lãng phí) đơn giản cho lập lịch công việc. Ngược lại, bộ lập lịch công việc thực hiện ít thường xuyên hơn. Có vài phút giữa việc tạo các tiến trình mới trong hệ thống. Bộ lập lịch công việc điều khiển mức độ đa nhiệm của hệ thống, tức là số tiến trình trong bộ nhớ. Nếu mức độ đa nhiệm ổn định thì tốc độ trung bình của việc tạo tiến trình phải bằng tốc độ khởi tạo trung bình của tiến trình rời hệ thống. Vì khoảng thời gian dài hơn giữa việc thực hiện nên bộ lập lịch công việc có thể cấp nhiều thời gian hơn để chọn một tiến trình thực hiện. Bộ lập lịch công việc phải thực hiện chọn lựa tiến trình để đưa vào hàng đợi sẵn sàng. Hầu hết các tiến trình có thể được mô tả như là tiến trình hướng nhập/xuất (I/O-bound proces) hay tiến trình hướng CPU (CPU-bound process). Một tiến trình hướng nhập/xuất mất nhiều thời gian để thực hiện nhập/xuất hơn thời gian tính toán. Ngược lại, một tiến trình hướng CPU phát sinh các yêu cầu nhập/xuất không thường xuyên, dùng thời gian để thực hiện việc tính toán nhiều hơn một tiến trình hướng nhập/xuất sử dụng. Bộ lập lịch công việc nên chọn sự kết hợp hài hoà 42
- giữa tiến trình hướng nhập/xuất và tiến trình hướng CPU. Nếu tất cả tiến trình là hướng nhập/xuất thì hàng đợi sẵn sàng sẽ luôn rỗng và bộ lập lịch CPU sẽ có ít công việc để thực hiện. Nếu tất cả tiến trình là hướng CPU thì hàng đợi nhập/xuất sẽ luôn rỗng, các thiết bị sẽ không được sử dụng và hệ thống sẽ mất cân bằng. Hệ thống có hiệu suất tốt nhất nếu có sự kết hợp các tiến trình hướng CPU và hướng nhập/xuất. Trong một vài hệ thống, bộ lập lịch công việc có thể không có hay rất ít. Thí dụ, các hệ thống chia sẻ thời gian như UNIX thường không có bộ lập lịch công việc, hệ thống sẽ đặt các tiến trình mới phát sinh vào bộ nhớ cho bộ lập lịch CPU. Khả năng ổn định của hệ thống này phụ thuộc vào giới hạn vật lý (như số lượng thiết bị cuối sẵn có) hay điều chỉnh tự nhiên của người sử dụng. Nếu năng lực thực hiện giảm tới mức độ không thể chấp nhận được thì một số người dùng sẽ thoát khỏi hệ thống. Một số hệ thống như hệ chia sẻ thời gian có thể bổ sung bộ lập lịch trung gian. Bộ lập lịch trung gian (medium-term process) dùng để xóa các tiến trình ra khỏi bộ nhớ trong đưa chúng ra bộ nhớ ngoài, do đó giảm mức độ đa nhiệm của hệ thống. Sau đó, tiến trình có thể được đưa trở lại bộ nhớ trong và việc thực hiện của tiến trình có thể được tiếp tục thực hiện. Cơ chế này được gọi là hoán vị (swapping). Tiến trình được hoán chuyển ra và sau đó được hoán chuyển vào bởi bộ lập lịch trung gian. Hoán chuyển là cần thiết để cải thiện sự kết hợp giữa các tiến trình hướng nhập/xuất và hướng CPU, hay vì một yêu cầu cấp phát bộ nhớ vượt quá kích thước bộ nhớ còn rỗi. Hoán chuyển sẽ được nghiên cứu kỹ hơn ở các phần sau. Hình 2.6 Lưu đồ bổ sung lập lịch trung bình tới hàng đợi 43
- 3) Chuyển trạng thái Trước khi chuyển CPU cho một tiến trình khác, cần lưu trạng thái của tiến trình cũ và nạp trạng thái đã được lưu của tiến trình mới. Công việc này được xem như chuyển trạng thái (context switch). Trạng thái của tiến trình được lưu trữ trong PCB của tiến trình đó; Nó chứa giá trị các thanh ghi, trạng thái tiến trình (Hình 2.1) và các thông tin quản lý bộ nhớ. Khi chuyển trạng thái xảy ra, hệ thống sẽ lưu trạng thái của tiến trình cũ vào trong PCB tương ứng của tiến trình, sau đó hệ thống sẽ nạp trạng thái được lưu của tiến trình mới được bộ lập lịch chọn để thực hiện. Thời gian chuyển trạng thái là chi phí lãng phí vì hệ thống không thực hiện công việc có ích trong khi chuyển trạng thái. Tốc độ chuyển trạng thái phụ thuộc vào tốc độ bộ nhớ, số lượng thanh ghi phải được sao chép và sự tồn tại của các chỉ thị đặc biệt (như chỉ thị để nạp và lưu tất cả thanh ghi). Thông thường, tốc độ nằm trong khoảng từ 1 tới 1000 micro giây. Những lần chuyển đổi trạng thái phụ thuộc nhiều vào hỗ trợ của phần cứng. Thí dụ, vài bộ xử lý (như Sun UltraSPARC) cung cấp nhiều tập thanh ghi. Một chuyển trạng thái đơn giản chứa chuyển đổi con trỏ tới tập thanh ghi hiện hành. Nếu tiến trình hoạt động vượt quá tập thanh ghi thì hệ thống sắp xếp lại dữ liệu thanh ghi tới và từ bộ nhớ. Cũng vì thế mà hệ điều hành phức tạp hơn và nhiều công việc được làm hơn trong khi chuyển trạng thái. Kỹ thuật quản lý bộ nhớ nâng cao có thể yêu cầu dữ liệu bổ sung để được chuyển với mỗi trạng thái. Thí dụ, không gian địa chỉ của tiến trình hiện hành phải được lưu khi không gian của công việc kế tiếp được chuẩn bị sử dụng. Không gian địa chỉ được lưu như thế nào và lượng công việc được yêu cầu để lưu nó phụ thuộc vào phương pháp quản lý bộ nhớ của hệ điều hành. Chuyển trạng thái có thể dẫn đến tắc nghẽn khi thực hiện vì thế các lập trình viên sử dụng các cấu trúc mới để tránh chuyển trạng thái trong các trường hợp có thể được. 4) Luồng Mô hình tiến trình xem xét ở trên được thiết kế để một tiến trình là một chương trình thực hiện đơn luồng. Thí dụ, nếu một tiến trình đang chạy một chương trình xử lý văn bản, một luồng đơn của chỉ thị đang được thực hiện. Đây là một luồng điều khiển đơn cho phép tiến trình thực hiện chỉ một lệnh tại một thời điểm. Thí dụ, người dùng không thể cùng lúc nhập các ký tự và chạy bộ kiểm tra chính tả trong cùng một 44
- tiến trình. Nhiều hệ điều hành hiện đại mở rộng khái niệm tiến trình, cho phép một tiến trình có nhiều luồng thực hiện (đa luồng). Do đó, chúng cho phép thực hiện nhiều hơn một lệnh tại một thời điểm. 2.1.3 Các thao tác trên tiến trình Các tiến trình trong hệ thống có thể thực hiện đồng thời, chúng phải được khởi tạo và xoá tự động. Do đó, hệ điều hành phải cung cấp một cơ chế cho việc tạo tiến trình và kết thúc tiến trình. 1) Tạo tiến trình Trong khi thực hiện, tiến trình có thể khởi tạo nhiều tiến trình mới, bằng lời gọi hệ thống create-process. Tiến trình tạo gọi là tiến trình cha, ngược lại các tiến trình mới được gọi là tiến trình con. Mỗi tiến trình mới này sau đó có thể tạo các tiến trình khác, hình thành một cây tiến trình (Hình 2.7). root pagedaem swapper init on user 1 user 2 user 3 Hình 2.7 Cây tiến trình trên một hệ thống UNIX điển hình Thông thường, một tiến trình sẽ cần các tài nguyên xác định (như thời gian CPU, bộ nhớ, tập tin, thiết bị nhập/xuất) để hoàn thành công việc của nó. Khi một tiến trình tạo một tiến trình con, tiến trình con có thể nhận tài nguyên nó yêu cầu trực tiếp từ hệ điều hành hay nó có thể bị ràng buộc tới một tập con các tài nguyên của tiến trình cha. Tiến trình cha có thể phải phân chia các tài nguyên giữa các tiến trình con hay có thể chia sẻ một số tài nguyên (như bộ nhớ và tập tin) giữa nhiều tiến trình con. Giới hạn một tiến trình con tới một tập con tài nguyên của tiến trình cha ngăn chặn bất cứ tiến trình từ nạp chồng hệ thống bằng cách tạo quá nhiều tiến trình con. Ngoài ra, khi một tiến trình được tạo nó lấy tài nguyên vật lý và logic khác nhau, dữ liệu khởi tạo (hay nhập) có thể được truyền từ tiến trình cha tới tiến trình 45
- con. Thí dụ, xét một tiến trình với toàn bộ chức năng là hiển thị trạng thái của một tập tin F1 trên màn hình. Khi nó được tạo, nó sẽ lấy dữ liệu vào từ tiến trình cha, tên của tập tin F1 và nó sẽ thực hiện dùng dữ liệu đó để lấy thông tin mong muốn. Nó có thể cũng lấy tên của thiết bị xuất dữ liệu. Một số hệ điều hành chuyển tài nguyên tới tiến trình con. Trên hệ thống như thế, tiến trình mới có thể lấy hai tập tin đang mở, F1 và thiết bị cuối, và có thể chỉ cần chuyển dữ liệu giữa hai tập tin. Khi một tiến trình tạo một tiến trình mới, có hai khả năng có thể sảy ra: - Tiến trình cha tiếp tục thực hiện đồng hành với tiến trình con của nó. - Tiến trình cha chờ cho tới khi một vài hay tất cả tiến trình con kết thúc. Cũng có hai khả năng sử dụng không gian địa chỉ của tiến trình mới: - Tiến trình con là bản sao của tiến trình cha. - Tiến trình con có một chương trình được nạp vào nó. Để hiển thị việc cài đặt khác nhau này, chúng ta xem xét hệ điều hành UNIX. Trong UNIX, mỗi tiến trình được xác định bởi định danh tiến trình (process identifier), là số nguyên duy nhất. Một tiến trình mới được tạo bởi lời gọi hệ thống fork. Tiến trình mới chứa bản sao không gian địa chỉ của tiến trình gốc. Cơ chế này cho phép tiến trình cha giao tiếp dễ dàng với tiến trình con. Cả hai tiến trình (cha và con) tiếp tục thực hiện tại chỉ thị sau khi lời gọi hệ thống fork, với một sự khác biệt: mã trả về cho lời gọi hệ thống fork là rỗng cho tiến trình con, ngược lại định danh tiến trình của tiến trình con được trả về tới tiến trình cha. Điển hình lời gọi hệ thống execlp được dùng sau lời gọi hệ thống fork bởi một trong hai tiến trình để thay thế không gian bộ nhớ với tiến trình mới. Lời gọi hệ thống execlp nạp tập tin nhị phân vào trong bộ nhớ, xóa hình ảnh bộ nhớ của chương trình chứa lời gọi hệ thống execlp, và bắt đầu việc thực hiện của nó. Theo cách này, hai tiến trình có thể giao tiếp và sau đó thực hiện cách riêng của chúng. Sau đó, tiến trình cha có thể tạo thêm tiến trình con, hay nếu nó không làm gì trong thời gian tiến trình con chạy thì nó sẽ phát ra lời gọi hệ thống wait để chuyển sang trạng thái chờ, và di chuyển vào hàng đợi sẵn sàng khi tiến trình con kết thúc. Chương trình C (Hình 2.8) hiển thị lời gọi hệ thống UNIX được mô tả trước đó. Tiến trình cha tạo một tiến trình con sử dụng lời gọi hệ thống fork. Bây giờ chúng ta có hai tiến trình khác nhau chạy một bản sao của cùng chương trình. Giá trị pid cho tiến trình con là 0; cho tiến trình 46
- cha là một số nguyên lớn hơn 0. Tiến trình con náp chồng không gian địa chỉ của nó với lệnh của UNIX là /bin/ls (được dùng để liệt kê thư mục) dùng lời gọi hệ thống execlp. Tiến trình cha chờ cho tiến trình con hoàn thành với lời gọi hệ thống wait. Khi tiến trình con hoàn thành, tiến trình cha bắt đầu lại từ lời gọi hệ thống wait nơi nó hoàn thành việc sử dụng lời gọi hệ thống exit. Ngược lại, hệ điều hành DEC VMS tạo một tiến trình mới, nạp chương trình xác định trong tiến trình đó và bắt đầu thực hiện nó. Hệ điều hành Microsoft Windows NT hỗ trợ cả hai mô hình: không gian địa chỉ của tiến trình cha có thể được sao lại hay tiến trình cha có thể xác định tên của một chương trình cho hệ điều hành nạp vào không gian địa chỉ của tiến trình mới. #include main(int argc, char* argv[]) { int pid; /*fork another process*/ pid = fork(); if(pid<0){ /*error occurred */ fprintf(stderr, “Fork Failed”); exit(-1); } else if (pid==0){ /*child process*/ execlp(“/bin/ls”,”ls”,NULL); } else { /*parent process*/ /*parent will wait for the child to complete*/ wait(NULL); printf(“Child Complete”); exit(0); } } Hình 2.8 Chương trình C tạo một tiến trình riêng rẽ 47
- 2) Kết thúc tiến trình Một tiến trình kết thúc khi nó hoàn thành việc thực hiện câu lệnh cuối cùng và yêu cầu hệ điều hành xóa nó bằng cách sử dụng lời gọi hệ thống exit. Tại thời điểm đó, tiến trình có thể trả về dữ liệu (đầu ra) tới tiến trình cha (bằng lời gọi hệ thống wait). Tất cả tài nguyên của tiến trình, gồm bộ nhớ vật lý và logic, các tập tin đang mở, vùng đệm nhập/xuất, được thu hồi bởi hệ điều hành. Việc kết thúc xảy ra trong các trường hợp khác. Một tiến trình có thể gây kết thúc một tiến trình khác bằng một lời gọi hệ thống hợp lý (thí dụ, abort). Thường chỉ có tiến trình cha bị kết thúc có thể gọi lời gọi hệ thống như thế. Ngược lại, người dùng có thể tùy ý loại bỏ mỗi công việc của các tiến trình còn lại. Do đó, tiến trình cha cần biết các định danh của các tiến trình con. Vì thế khi một tiến trình tạo một tiến trình mới, định danh của mỗi tiến trình mới được tạo được truyền tới cho tiến trình cha. Một tiến trình cha có thể kết thúc việc thực hiện của một trong những tiến trình con với nhiều lý do khác nhau: - Tiến trình con sử dụng tài nguyên vượt quá mức được cấp. Điều này yêu cầu tiến trình cha có một cơ chế để xem xét trạng thái của các tiến trình con. - Công việc được gán tới tiến trình con không còn cần thiết nữa. - Tiến trình cha đang kết thúc và hệ điều hành không cho phép một tiến trình con tiếp tục nếu tiến trình cha kết thúc. Trên những hệ thống như thế, nếu một tiến trình kết thúc (bình thường hoặc không bình thường), thì tất cả tiến trình con cũng phải kết thúc. Trường hợp này được xem như kết thúc xếp tầng (cascading termination) thường được khởi tạo bởi hệ điều hành. Để hiển thị việc thực hiện và kết thúc tiến trình, xem xét hệ điều hành UNIX chúng ta có thể kết thúc một tiến trình dùng lời gọi hệ thống exit; nếu tiến trình cha có thể chờ cho đến khi tiến trình con kết thúc bằng lời gọi hệ thống wait. Lời gọi hệ thống wait trả về định danh của tiến trình con bị kết thúc để tiến trình cha có thể xác định những tiến trình con nào có thể kết thúc. Tuy nhiên, nếu tiến trình cha kết thúc thì tất cả tiến trình con của nó được gán như tiến trình cha mới. Do đó, các tiến trình con chỉ có một tiến trình cha để tập hợp trạng thái và thống kê việc thực hiện. 48
- 2.1.4 Hợp tác giữa các tiến trình Các tiến trình đồng thời thực hiện trong hệ điều hành có thể là những tiến trình độc lập hay những tiến trình hợp tác. Một tiến trình là độc lập (independent) nếu nó không thể ảnh hưởng hay bị ảnh hưởng bởi các tiến trình khác thực hiện trong hệ thống. Rõ ràng, bất kỳ một tiến trình không chia sẻ bất cứ dữ liệu (tạm thời hay cố định) với tiến trình khác là độc lập. Ngược lại, một tiến trình là hợp tác (cooperating) nếu nó có thể ảnh hưởng hay bị ảnh hưởng bởi các tiến trình khác trong hệ thống. Hay nói cách khác, bất cứ tiến trình chia sẻ dữ liệu với tiến trình khác là tiến trình hợp tác. Chúng ta có thể cung cấp một môi trường cho phép các tiến trình hợp tác với nhiều lý do: - Chia sẻ thông tin: vì nhiều người dùng có thể quan tâm cùng thông tin (thí dụ tập tin chia sẻ), hệ điều hành phải cung cấp một môi trường cho phép truy xuất đồng hành tới những loại tài nguyên này. - Gia tăng tốc độ tính toán: nếu chúng ta muốn một công việc chạy nhanh hơn, chúng ta phải chia nó thành những công việc nhỏ hơn, mỗi công việc sẽ thực hiện song song với các tác vụ khác. Việc tăng tốc như thế có thể đạt được chỉ nếu máy tính có nhiều thành phần đa xử lý (như nhiều CPU hay các kênh I/O). - Tính module hóa: chúng ta muốn xây dựng hệ thống thành các module, chia các chức năng hệ thống thành những tiến trình hay luồng. - Tính tiện dụng: một người sử dụng có thể có nhiều công việc thực hiện tại cùng thời điểm. Thí dụ, một người dùng có thể đang soạn thảo, in, và biên dịch cùng một lúc. Việc thực hiện đồng thời của các tiến trình hợp tác sẽ yêu cầu các cơ chế cho phép các tiến trình giao tiếp với các tiến trình khác và đồng bộ hóa các hoạt động của chúng. Để minh họa khái niệm của các tiến trình cộng tác, chúng ta xem xét bài toán người sản xuất - người tiêu thụ, là mô hình chung cho các tiến trình hợp tác. Tiến trình người sản xuất cung cấp thông tin được tiêu thụ bởi tiến trình người tiêu thụ. Thí dụ, một chương trình in sản xuất các ký tự được tiêu thụ bởi trình điều khiển máy in. Một trình biên dịch có thể sản xuất mã hợp ngữ được tiêu thụ bởi trình hợp ngữ. Sau đó, trình hợp ngữ có sản xuất module đối tượng, được tiêu thụ bởi bộ nạp. 49
- Để cho phép người sản xuất và người tiêu thụ chạy đồng hành, chúng ta phải có sẵn một vùng đệm chứa các sản phẩm có thể được điền vào bởi người sản xuất và được lấy đi bởi người tiêu thụ. Người sản xuất có thể sản xuất một sản phẩm trong khi người tiêu thụ đang tiêu thụ một sản phẩm khác. Người sản xuất và người tiêu thụ phải được đồng bộ để người tiêu thụ không tiêu thụ một sản phẩm mà chưa được sản xuất. Trong trường hợp này, người tiêu thụ phải chờ cho tới khi các sản phẩm mới được tạo ra. Bài toán người sản xuất - người tiêu thụ với vùng đệm không bị giới hạn (unbounded-buffer) thiết lập không giới hạn kích thước của vùng đệm. Người tiêu thụ có thể phải chờ các sản phẩm mới nhưng người sản xuất có thể luôn tạo ra sản phẩm mới. Vấn đề người sản xuất - người tiêu thụ với vùng đệm có kích thước giới hạn (bounded-buffer) đảm bảo một kích thước cố định cho vùng đệm. Trong trường hợp này, người tiêu thụ phải chờ nếu vùng đệm rỗng, và người sản xuất phải chờ nếu vùng đệm đầy. Vùng đệm có thể được cung cấp bởi hệ điều hành thông qua việc sử dụng phương tiện giao tiếp liên tiến trình (interprocess communication - IPC), hay được mã hóa cụ thể bởi người lập trình ứng dụng với việc sử dụng bộ nhớ được chia sẻ. Để chúng ta hiển thị một giải pháp chia sẻ bộ nhớ đối với vấn đề vùng đệm bị giới hạn (bounded-buffer). Tiến trình người sản xuất và người tiêu thụ chia sẻ các biến sau: #define BUFFER_SIZE 10 typedef struct{ } item; item buffer[BUFFER_SIZE]; int in = 0; int out = 0; Vùng đệm được chia sẻ được cài đặt như một mảng vòng với hai con trỏ luận lý: in và out. Biến in chỉ tới vị trí trống kế tiếp trong vùng đệm; out chỉ tới vị trí đầy đầu tiên trong vùng đệm. Vùng đệm là rỗng khi in==out; vùng đệm là đầy khi ((in + 1)%BUFFER_SIZE) ==out. 50
- Mã lệnh cho tiến trình người sản xuất và người tiêu thụ được trình bày dưới đây. Tiến trình người sản xuất có một biến nextProduced trong đó sản phẩm mới được tạo ra và được lưu trữ: while (1) { /*produce an item in nextProduced*/ while (((in + 1)%BUFFER_SIZE) ==out) ; /*do nothing*/ buffer[in] = nextProduced; in = (in + 1) % BUFFER_SIZE; } Tiến trình người tiêu thụ có biến cục bộ nextConsumed trong đó sản phẩm được tiêu thụ và được lưu trữ: while (1){ while (in==out) ; //nothing nextConsumed = buffer[out]; out = (out + 1) % BUFFER_SIZE; /*consume the item in nextConsumed*/ } Cơ chế này cho phép nhiều nhất BUFFER_SIZE –1 trong vùng đệm tại cùng một thời điểm. Trong phần trên chúng ta đã hiển thị cách mà các tiến trình hợp tác có thể giao tiếp với nhau trong một môi trường chia sẻ bộ nhớ. Cơ chế yêu cầu các tiến trình này chia sẻ nhóm vùng đệm chung và mã cho việc cài đặt vùng đệm được viết trực tiếp bởi người lập trình ứng dụng. Một cách khác đạt được cùng ảnh hưởng cho hệ điều hành là cung cấp phương tiện cho các tiến trình hợp tác giao tiếp với nhau bằng một phương tiện giao tiếp liên tiến trình (IPC). IPC cung cấp một cơ chế cho phép một tiến trình giao tiếp và đồng bộ các hoạt động của chúng mà không chia sẻ cùng không gian địa chỉ. IPC đặc biệt có ích trong môi trường phân tán nơi các tiến trình giao tiếp có thể thường trú trên các máy tính khác được nối kết qua mạng. Thí dụ chương trình chat được dùng trên World Wide Web. 51
- IPC được cung cấp bởi hệ thống truyền thông điệp, và các hệ thống truyền thông điệp có thể được định nghĩa trong nhiều cách. Trong phần này chúng ta sẽ xem xét những vấn đề khác nhau khi thiết kế các hệ thống truyền thông điệp. 2.1.5 Luồng 1) Tổng quan Một luồng là đơn vị cơ bản của việc sử dụng CPU; nó bao gồm: một định danh luồng (thread ID), một bộ đếm chương trình, tập thanh ghi và ngăn xếp. Nó chia sẻ với các luồng khác thuộc cùng một tiến trình phần mã, phần dữ liệu, và tài nguyên hệ điều hành như các tập tin đang mở. Một tiến trình truyền thống có một luồng điều khiển đơn. Nếu tiến trình có nhiều luồng điều khiển, nó có thể thực hiện nhiều hơn một công việc tại một thời điểm. Hình 2.9 hiển thị sự khác nhau giữa tiến trình đơn luồng và tiến trình đa luồng. - Sự cơ động Nhiều phần mềm chạy trên các máy tính là đa luồng. Một ứng dụng có thể được cài đặt như một tiến trình riêng rẽ với nhiều luồng điều khiển, điển hình như trình duyệt Web có thể có một luồng hiển thị hình ảnh, văn bản trong khi một luồng khác lấy dữ liệu từ mạng. Một trình soạn thảo văn bản có thể có một luồng hiển thị đồ họa, luồng thứ hai đọc sự bấm phím trên bàn phím từ người dùng, một luồng thứ ba thực hiện việc kiểm tra chính tả và từ vựng chạy trong chế độ nền. Hình 2.9 Tiến trình đơn và đa luồng Trong những trường hợp cụ thể một ứng dụng đơn có thể được yêu cầu thực hiện nhiều công việc đơn. Thí dụ, một trình phục vụ web chấp nhận các yêu cầu khách hàng như trang web, hình ảnh, âm thanh, Một trình phục vụ web có thể có 52
- nhiều (hàng trăm) khách hàng truy xuất đồng thời nó. Nếu trình phục vụ web chạy như một tiến trình đơn luồng truyền thống thì nó sẽ có thể chỉ phục vụ một khách hàng tại cùng thời điểm. Lượng thời gian mà khách hàng phải chờ yêu cầu của nó được phục vụ là rất lớn. Một giải pháp là có một trình phục vụ chạy như một tiến trình đơn chấp nhận các yêu cầu. Khi trình phục vụ nhận một yêu cầu, nó sẽ tạo một tiến trình riêng để phục vụ yêu cầu đó. Phương pháp tạo ra tiến trình này là cách sử dụng thông thường trước khi luồng trở nên phổ biến. Tạo ra tiến trình có ảnh hưởng rất lớn như được trình bày ở chương trước. Nếu tiến trình mới sẽ thực hiện cùng công việc như tiến trình đã có thì tại sao lại gánh chịu tất cả chi phí đó? Thường sẽ hiệu quả hơn cho một tiến trình chứa nhiều luồng phục vụ cùng một mục đích. Tiếp cận này sẽ đa luồng tiến trình trình phục vụ web. Trình phục vụ sẽ tạo một luồng riêng kiểm tra các yêu cầu người dùng; khi yêu cầu được thực hiện nó không tạo ra tiến trình khác mà sẽ tạo một luồng khác phục vụ yêu cầu. Luồng cũng đóng một vai trò quan trọng trong hệ thống lời gọi thủ tục từ xa (Remote Process Call - RPC). RPCs cho phép giao tiếp liên tiến trình bằng cách cung cấp cơ chế giao tiếp tương tự như các lời gọi hàm hay thủ tục thông thường. Điển hình, các trình phục vụ RPCs là đa luồng. Khi một trình phục vụ nhận một thông điệp, nó phục vụ thông điệp dùng một luồng riêng. Điều này cho phép phục vụ nhiều yêu cầu đồng thời. - Thuận lợi + Sự đáp ứng: đa luồng một ứng dụng giao tiếp cho phép một chương trình tiếp tục chạy thậm chí nếu một phần của nó bị khóa hay đang thực hiện một thao tác có thời gian thực hiện dài, do đó gia tăng sự đáp ứng đối với người dùng. Thí dụ, một trình duyệt web vẫn có thể đáp ứng người dùng bằng một luồng trong khi một ảnh đang được nạp bằng một luồng khác. + Chia sẻ tài nguyên: các luồng của một tiến trình chia sẻ bộ nhớ và các tài nguyên đã được cấp cho tiến trình đó. Thuận lợi của việc chia sẻ mã lệnh là nó cho phép một ứng dụng có nhiều hoạt động của các luồng khác nhau nằm trong cùng không gian địa chỉ. 53
- + Kinh tế: cấp phát bộ nhớ và các tài nguyên cho việc tạo các tiến trình là rất tốn kém. Vì các luồng trong một tiến trình chia sẻ chung tài nguyên của tiến trình nên sẽ kinh tế hơn để tạo và chuyển trạng thái giữa các luồng. Rất khó để đánh giá sự khác biệt chi phí cho việc tạo và duy trì một tiến trình so với một luồng, nhưng thường sẽ mất nhiều thời gian để tạo và quản lý một tiến trình hơn một luồng. Trong Solaris 2, tạo một tiến trình chậm hơn khoảng 30 lần tạo một luồng và chuyển đổi trạng thái chậm hơn 5 lần. + Sử dụng kiến trúc đa xử lý: các ưu điểm của đa luồng có thể phát huy rất tốt trong kiến trúc đa xử lý, ở đó mỗi luồng song song thực hiện trên một bộ xử lý khác nhau. Một tiến trình đơn luồng chỉ có thể chạy trên một CPU. Đa luồng trên một máy nhiều CPU gia tăng tính đồng hành. Trong kiến trúc đơn xử lý, CPU thường chuyển đổi qua lại giữa mỗi luồng quá nhanh để tạo ra hình ảnh của sự song song nhưng trong thực tế chỉ một luồng đang chạy tại một thời điểm. 2) Luồng người sử dụng và luồng nhân - Luồng người sử dụng: được hỗ trợ bởi nhân và được cài đặt thư viện luồng tại cấp người dùng. Thư viện cung cấp hỗ trợ cho việc tạo luồng, lập lịch, và quản lý mà không có sự hỗ trợ từ nhân. Vì nhân không biết các luồng cấp người dùng, tất cả việc tạo luồng và lập thời biểu được thực hiện trong không gian người dùng mà không cần sự can thiệp của nhân. Do đó, các luồng cấp người dùng thường tạo và quản lý nhanh chóng, tuy nhiên chúng cũng có những trở ngại. Thí dụ, nếu nhân là đơn luồng thì bất cứ luồng cấp người dùng thực hiện một lời gọi hệ thống nghẽn sẽ làm cho toàn bộ tiến trình bị nghẽn, thậm chí nếu các luồng khác sẵn dùng để chạy trong ứng dụng. Các thư viện luồng người dùng gồm các luồng POSIX Pthreads, Mach C-threads và Solaris 2 UI-threads. - Luồng nhân: được hỗ trợ trực tiếp bởi hệ điều hành. Nhân thực hiện việc tạo luồng, lập lịch, và quản lý không gian nhân. Vì quản lý luồng được thực hiện bởi hệ điều hành, luồng nhân thường tạo và quản lý chậm hơn luồng người dùng. Tuy nhiên, vì nhân được quản lý các luồng nếu một luồng thực hiện lời gọi hệ thống bế tắc, nhân có thể lập lịch một luồng khác trong ứng dụng thực hiện. Trong môi trường đa xử lý, nhân có thể lập thời biểu luồng trên một bộ xử lý khác. Hầu hết các hệ điều hành hiện 54