🔙 Quay lại trang tải sách pdf ebook Giáo trình lý thuyết hệ điều hành
Ebooks
Nhóm Zalo
ĐẠI HỌC HUẾ
TRƯỜNG ĐẠI HỌC KHOA HỌC
KHOA CÔNG NGHỆ THÔNG TIN
🙡 🕮 🙣
GIÁO TRÌNH
LÝ THUYẾT HỆ ĐIỀU HÀNH BIÊN SOẠN: NGUYỄN KIM TUẤN
Huế 06/2004
MỤC LỤC
Trang
Chương I: TỔNG QUAN VỀ HỆ ĐIỀU HÀNH
I.1. Chức năng và lịch sử phát triển của hệ điều hành .............................. 1 I.1.1. Chức năng của hệ điều hành ............................................................. 1 I.1.2. Lịch sử phát triển của hệ điều hành .................................................. 3
I.2. Một số khái niệm của hệ điều hành ..................................................... 5 I.2.1. Tiến trình (Process) và tiểu trình (Thread)....................................... 5 I.2.2. Bộ xử lý lệnh (Shell) ........................................................................ 5 I.2.3. Sự phân lớp hệ thống (System Layering)......................................... 6 I.2.4. Tài nguyên hệ thống (System Resources) ....................................... 7 I.2.5. Lời gọi hệ thống (System Calls) ...................................................... 7
I.3. Hệ điều hành và phân loại hệ điều hành .............................................. 8 I.3.1. Hệ điều hành là gì? .......................................................................... 8 I.3.2. Phân loại hệ điều hành ..................................................................... 9
I.4. Thành phần và cấu trúc của hệ điều hành ......................................... 12 I.4.1. Các thành phần của hệ điều hành .................................................. 12 I.4.2. Các cấu trúc của hệ điều hành ........................................................ 16
I.5. Hệ điều hành Windows95 ................................................................... 21 I.5.1. Giới thiệu về hệ điều hành Windows95 ......................................... 22 I.5.2. Cấu trúc của windows95 ................................................................ 24 I.5.3. Bộ nhớ ảo trong windows95 .......................................................... 25
I.6. Hệ điều hành Windows 2000 .............................................................. 26 I.6.1. Giới thiệu về hệ điều hành Windows 2000 ................................... 26 I.6.2. Một số đặc tính của Windows 2000 ............................................... 27 I.6.3. Một số khái niệm trong Windows 2000 ........................................ 28 I.6.4. Kiến trúc của Windows 2000 ........................................................ 31 I.7. Hệ điều hành Linux ............................................................................. 37
Chương II: QUẢN LÝ TIẾN TRÌNH
II.1. Tổng quan về tiến trình ..................................................................... 41 I.1.1. Tiến trình và các loại tiến trình ...................................................... 41
I.1.2. Mô hình tiến trình .......................................................................... 42 I.1.3. Tiểu trình và tiến trình ................................................................... 45 I.1.4. Các trạng thái tiến trình ................................................................. 46 I.1.5. Cấu trúc dữ liệu của khối quản lý tiến trình .................................. 50
I.1.6. Các thao tác điều khiển tiến trình .................................................. 52 II.2. Tài nguyên găng và đoạn găng ....................................................53 II.2.1.Tài nguyên găng (Critical Resource) ............................................ 53
II.2.2.Đoạn găng (Critical Section) ........................................................ 57 II.2.3.Yêu cầu của công tác điều độ qua đoạn găng ............................... 59 II.3. Điều độ tiến trình qua đoạn găng .................................................60 II.3.1. ...............................................................................................Các giải pháp phần cứng ............................................................................ 60 II.3.2. ...............................................................................................Các giải pháp dùng biến khoá .................................................................... 62 II.3.3. ...............................................................................................Các giải pháp được hỗ trợ bởi hệ điều hành và ngôn ngữ lập trình............ 63 II.3.4. ...............................................................................................Hai bài toán điều phối làm ví dụ ................................................................ 72 II.4. Tắc nghẽn (Deadlock) và chống tắc nghẽn ..................................... 79 II.4.1.......................................................................................... T ắc nghẽn ................................................................................................... 79 II.4.2.Điều kiện hình thành tắt nghẽn ..................................................... 81 II.4.3.Ngăn chặn tắc nghẽn (Deadlock Prevention) ............................... 81 II.4.4.Nhận biết tắc nghẽn (Deadlock Detection) ................................... 81 II.5. Điều phối tiến trình
II.5.1.Mục tiêu điều phối ........................................................................ 83 II.5.2.Tổ chức điều phối ......................................................................... 86 II.5.3.Các chiến lược điều phối ............................................................... 87 II.6. Tiến trình trong Windows NT .......................................................... 89
Chương III: QUẢN LÝ BỘ NHỚ
III.1. Nhiệm vụ của quản lý bộ nhớ .......................................................... 93 III.2. Kỹ thuật cấp phát bộ nhớ (nạp chương trình vào bộ nhớ chính) 95 III.2.1.Kỹ thuật phân vùng cố định (Fixed Partitioning) ....................... 95 III.2.2. Kỹ thuật phân vùng động (Dynamic Partitioning) .................... 97
III.2.3.Kỹ thuật phân trang đơn (Simple Paging) ................................. 103 III.2.4. Kỹ thuật phân đoạn đơn (Simple Segmentation)…………………...106 III.3. Kỹ thuật bộ nhớ ảo (Virtual Memory)........................................... 109 III.3.1.Bộ nhớ ảo .................................................................................. 109 III.3.2.Kỹ thuật bộ nhớ ảo ................................................................... 112 III.4. Quản lý bộ nhớ RAM của DOS ..................................................... 126 III.5.a...............................................................................................Progr am Segment Prefix (PSP) ..................................................................... 126 III.5.b. .............................................................................................Chươ ng trình COM và EXE ................................................................................. III.5.c...............................................................................................Mem ory Control Block (MCB) ........................................................................... III.5.Sự phân trang/đoạn trong hệ điều hành Windown NT ................ 130 III.5.a.Segmentation ............................................................................ 130 III.5.b.Paging....................................................................................... 132 III.6. Các thuật toán thay trang .............................................................. 133 III.7. Cấp phát khung trang .................................................................... 136 III.8. Một số vấn đề về quản lý bộ nhớ của Windows 2000 .................. 137 III.8.1. Nhiệm vụ quản lý bộ nhớ của Windows 2000 ......................... 137 III.8.2. Các dịch vụ trình quản lý bộ nhớ cung cấp .............................. 138 III.8.3. Address Space Layout .............................................................. 141 III.8.4. Chuyển đổi địa chỉ .................................................................... 142
Chương IV: QUẢN LÝ FILE và Đ ĨA
IV.1. Tổng quan về quản lý tập tin và đĩa............................................... 148 1. Tập tin và hệ thống quản lý tập tin............................................. 148 2. Bảng danh mục và tập tin chia sẻ............................................... 151 3. Quản lý không gian đĩa .............................................................. 153 4. Quản lý các block chứa file trên đĩa........................................... 155 5. An toàn trong quản lý tập tin...................................................... 158 6. Hiệu suất hệ thống file ............................................................... 162
IV.2. Các điều khiển hệ thống tập tin...................................................... 164 IV.3. Các hệ thống file trên các hệ điều hành hiện nay ......................... 166 IV.4. Tổ chức đĩa của MS_DOS ............................................................... 167 IV.5. Quản lý file trên đĩa của MS_DOS................................................. 172
IV.6. Tổ chức bảng thư mục gốc của Windows98 ................................. 185 IV.7. Tổ chức đĩa của windows 2000 ...................................................... 188 IV.7.1.Các loại partition ....................................................................... 188 IV.7.2.Các loại volume multipartition.................................................. 192 IV.8. Quản lý lưu trữ file trên đĩa của windowsNT/2000 ...................... 195 IV.8.1. Một số chức năng được hỗ trợ bởi NTFS của windows 2000. 195 IV.8.2. Cấu trúc của MFT.................................................................... 196 IV.8.3. Quản lý danh sách các block chứa file trên đĩa ...................... 203 IV.9. Một số kỹ thuật được hỗ trợ bởi hệ thống file NTFS ................... 206 IV.9.1.Lập bảng chỉ mục...................................................................... 206 IV.9.2.Ánh xạ Bad-cluster .................................................................. 207 IV.10.Tổ chức lưu trữ file trên đĩa CD_ROM......................................... 209
Mục lục......................................................................................... 212 Tài liệu tham khảo...................................................................... 215
Chương I
TỔNG QUAN VỀ HỆ ĐIỀU HÀNH
Nếu không có phần mềm, máy tính chỉ là một thiết bị điện tử thông thường. Với sự hỗ trợ của phần mềm, máy tính có thể lưu trữ, xử lý thông tin và người sử dụng có thể gọi lại được thông tin này. Phần mềm máy tính có thể chia thành nhiều loại: chương trình hệ thống, quản lý sự hoạt động của chính máy tính. Chương trình ứng dụng, giải quyết các vấn đề liên quan đến việc sử dụng và khai thác máy tính của người sử dụng. Hệ điều hành thuộc nhóm các chương trình hệ thống và nó là một chương trình hệ thống quan trọng nhất đối với máy tính và cả người sử dụng. Hệ điều hành điều khiển tất cả các tài nguyên của máy tính và cung cấp một môi trường thuận lợi để các chương trình ứng dụng do người sử dụng viết ra có thể chạy được trên máy tính. Trong chương này chúng ta xem xét vai trò của hệ điều hành trong trường hợp này.
Một máy tính hiện đại có thể bao gồm: một hoặc nhiều processor, bộ nhớ chính, clocks, đĩa, giao diện mạng, và các thiết bị vào/ra khác. Tất cả nó tạo thành một hệ thống phức tạp. Để viết các chương trình để theo dõi tất cả các thành phần của máy tính và sử dụng chúng một cách hiệu quả, người lập trình phải biết processor thực hiện chương trình như thế nào, bộ nhớ lưu trữ thông tin như thế nào, các thiết bị đĩa làm việc (ghi/đọc) như thế nào, lỗi nào có thể xảy ra khi đọc một block đĩa, … đây là những công việc rất khó khăn và quá khó đối với người lập trình. Nhưng rất may cho cả người lập trình ứng dụng và người sử dụng là những công việc trên đã được hệ điều hành hỗ trợ nên họ không cần quan tâm đến nữa. Chương này cho chúng ta một cái nhìn tổng quan về những gì liên quuan đến việc thiết kế cài đặt cũng như chức năng của hệ điều hành để hệ điều hành đạt được mục tiêu: Giúp người sử dụng khai thác máy tính dễ dàng và chương trình của người sử dụng có thể chạy được trên máy tính.
I.8. Chức năng và lịch sử phát triển của hệ điều hành I.1.7. Chức năng của hệ điều hành
Một hệ thống máy tính gồm 3 thành phần chính: phần cứng, hệ điều hành và các chương trình ứng dụng và người sử dụng. Trong đó hệ điều hành là một bộ phận quan trọng và không thể thiếu của hệ thống máy tính, nhờ có hệ điều hành mà
người sử dụng có thể đối thoại và khai thác được các chức năng của phần cứng máy tính.
Có thể nói hệ điều hành là một hệ thống các chương trình đóng vai trò trung gian giữa người sử dụng và phần cứng máy tính. Mục tiêu chính của nó là cung cấp một môi trường thuận lợi để người sử dụng dễ dàng thực hiện các chương trình ứng dụng của họ trên máy tính và khai thác triệt để các chức năng của phần cứng máy tính.
Để đạt được mục tiêu trên hệ điều hành phải thực hiện 2 chức năng chính sau đây:
❑ Giả lập một máy tính mở rộng: Máy tính là một thiết bị vi điện tử, nó được cấu thành từ các bộ phận như: Processor, Memory, I/O Device, Bus, ... , do đó để đối thoại hoặc khai thác máy tính người sử dụng phải hiểu được cơ chế hoạt động của các bộ phận này và phải tác động trực tiếp vào nó, tất nhiên là bằng những con số 0,1 (ngôn ngữ máy). Điều này là quá khó đối với người sử dụng. Để đơn giản cho người sử dụng hệ điều hành phải che đậy các chi tiết phần cứng máy tính bởi một máy tính mở rộng, máy tính mở rộng này có đầy đủ các chức năng của một máy tính thực nhưng đơn giản và dễ sử dụng hơn. Theo đó khi cần tác động vào máy tính thực người sử dụng chỉ cần tác động vào máy tính mở rộng, mọi sự chuyển đổi thông tin điều khiển từ máy tính mở rộng sang máy tính thực hoặc ngược lại đều do hệ điều hành thực hiện. Mục đích của chức năng này là: Giúp người sử dụng khai thác các chức năng của phần cứng máy tính dễ dàng và hiệu quả hơn.
❑ Quản lý tài nguyên của hệ thống: Tài nguyên hệ thống có thể là: processor, memory, I/O device, printer, file, ..., đây là những tài nguyên mà hệ điều hành dùng để cấp phát cho các tiến trình, chương trình trong quá trình điều khiển sự hoạt động của hệ thống. Khi người sử dụng cần thực hiện một chương trình hay khi một chương trình cần nạp thêm một tiến trình mới vào bộ nhớ thì hệ điều hành phải cấp phát không gian nhớ cho chương trình, tiến trình đó để chương trình, tiến trình đó nạp được vào bộ nhớ và hoạt động được. Trong môi trường hệ điều hành đa nhiệm có thể có nhiều chương trình, tiến trình đồng thời cần được nạp vào bộ nhớ, nhưng không gian lưu trữ của bộ nhớ có giới hạn, do đó hệ điều hành phải tổ chức cấp phát bộ nhớ sao cho hợp lý để đảm bảo tất cả các chương trình, tiến trình khi cần đều được nạp vào bộ nhớ để hoạt động. Ngoài ra hệ điều hành còn phải tổ chức bảo vệ các không gian nhớ đã cấp cho các chương trình, tiến trình để tránh sự truy cập bất hợp lệ và sự tranh chấp bộ nhớ giữa các chương trình, tiến trình, đặc biệt là các tiến trình đồng thời hoạt động trên hệ thống. Đây là một trong những nhiệm vụ quan trọng của hệ điều hành.
Trong quá trình hoạt động của hệ thống, đặc biệt là các hệ thống đa người dùng, đa chương trình, đa tiến trình, còn xuất hiện một hiện tượng khác, đó là nhiều
chương trình, tiến trình đồng thời sử dụng một không gian nhớ hay một tập tin (dữ liệu, chương trình) nào đó. Trong trường hợp này hệ điều hành phải tổ chức việc chia sẻ và giám sát việc truy xuất đồng thời trên các tài nguyên nói trên sao cho việc sử dụng tài nguyên có hiệu quả nhưng tránh được sự mất mát dữ liệu và làm hỏng các tập tin.
Trên đây là hai dẫn chứng điển hình để chúng ta thấy vai trò của hệ điều hành trong việc quản lý tài nguyên hệ thống, sau này chúng ta sẽ thấy việc cấp phát, chia sẻ, bảo vệ tài nguyên của hệ điều hành là một trong những công việc khó khăn và phức tạp nhất. Hệ điều hành đã chi phí nhiều cho công việc nói trên để đạt được mục tiêu: Trong mọi trường hợp tất cả các chương trình, tiến trình nếu cần được cấp phát tài nguyên để hoạt động thì sớm hay muộn nó đều được cấp phát và được đưa vào trạng thái hoạt động.
⮚ Trên đây là hai chức năng tổng quát của một hệ điều hành, đó cũng được xem như là các mục tiêu mà các nhà thiết kế, cài đặt hệ điều hành phải hướng tới. Các hệ điều hành hiện nay có các chức năng cụ thể sau đây:
❑ Hệ điều hành cho phép thực hiện nhiều chương trình đồng thời trong môi trường đa tác vụ - Multitasking Environment. Hệ điều hành multitasking bao gồm: Windows NT, Windows 2000, Linux và OS/2. Trong hệ thống multasking hệ điều hành phải xác định khi nào thì một ứng dụng được chạy và mỗi ứng dụng được chạy trong khoản thời gian bao lâu thì phải dừng lại để cho các ứng dụng khác được chạy.
❑ Hệ điều hành tự nạp nó vào bộ nhớ - It loads itself into memory: Quá trình nạp hệ điều hành vào bộ nhớ được gọi là quá trình Booting. Chỉ khi nào hệ điều hành đã được nạp vào bộ nhớ thì nó mới cho phép người sử dụng giao tiếp với phần cứng. Trong các hệ thống có nhiều ứng dụng đồng thời hoạt động trên bộ nhớ thì hệ điều hành phải chịu trách nhiệm chia sẻ không gian bộ nhớ RAM và bộ nhớ cache cho các ứng dụng này.
❑ Hệ điều hành và API: Application Programming Interface: API là một tập các hàm/thủ tục được xây dựng sẵn bên trong hệ thống, nó có thể thực hiện được nhiều chức năng khác nhau như shutdown hệ thống, đảo ngược hiệu ứng màn hình, khởi động các ứng dụng, … Hệ điều hành giúp cho chương trình của người sử dụng giao tiếp với API hay thực hiện một lời gọi đến các hàm/thủ tục của API.
❑ Nạp dữ liệu cần thiết vào bộ nhớ - It loads the requied data into memory: Dữ liệu do người sử dụng cung cấp được đưa vào bộ nhớ để xử lý. Khi nạp dữ liệu vào bộ nhớ hệ điều hành phải lưu lại địa chỉ của bộ nhớ nơi mà dữ liệu được lưu ở đó. Hệ điều hành phải luôn theo dõi bản đồ cấp phát bộ nhớ, nơi dữ liệu
và chương trình được lưu trữ ở đó. Khi một chương trình cần đọc dữ liệu, hệ điều hành sẽ đến các địa chỉ bộ nhớ nơi đang lưu trữ dữ liệu mà chương trình cần đọc để đọc lại nó.
❑ Hệ điều hành biên dịch các chỉ thị chương trình - It interprets program instructions: Hệ điều hành phải đọc và giải mã các thao tác cần được thực hiện, nó được viết trong chương trình của người sử dụng. Hệ điều hành cũng chịu trách nhiệm sinh ra thông báo lỗi khi hệ thống gặp lỗi trong khi đang hoạt động.
❑ Hệ điều hành quản lý tài nguyên - It managers resources: Nó đảm bảo việc sử dụng thích hợp tất cả các tài nguyên của hệ thống như là: bộ nhớ, đĩa cứng, máy in, …
I.1.8. Lịch sử phát triển của hệ điều hành
I.1.2.a.Thế hệ 1 (1945 - 1955):
Vào những năm 1950 máy tính dùng ống chân không ra đời. Ở thế hệ này mỗi máy tính được một nhóm người thực hiện, bao gồm việc thiết kế, xây dựng chương trình, thao tác, quản lý, ....
Ở thế hệ này người lập trình phải dùng ngôn ngữ máy tuyệt đối để lập trình. Khái niệm ngôn ngữ lập trình và hệ điều hành chưa được biết đến trong khoảng thời gian này.
I.1.2.b. Thế hệ 2 (1955 - 1965):
Máy tính dùng bán dẫn ra đời, và được sản xuất để cung cấp cho khách hàng. Bộ phận sử dụng máy tính được phân chia rõ ràng: người thiết kế, người xây dựng, người vận hành, người lập trình, và người bảo trì. Ngôn ngữ lập trình Assembly và Fortran ra đời trong thời kỳ này. Với các máy tính thế hệ này để thực hiện một thao tác, lập trình viên dùng Assembly hoặc Fortran để viết chương trình trên phiếu đục lỗ sau đó đưa phiếu vào máy, máy thực hiện cho kết qủa ở máy in.
Hệ thống xử lý theo lô cũng ra đời trong thời kỳ này. Theo đó, các thao tác cần thực hiện trên máy tính được ghi trước trên băng từ, hệ thống sẽ đọc băng từ , thực hiện lần lượt và cho kết quả ở băng từ xuất. Hệ thống xử lý theo lô hoạt động dưới sự điều khiển của một chương trình đặc biệt, chương trình này là hệ điều hành sau này.
I.1.2.c. Thế hệ 3 (1965 - 1980)
Máy IBM 360 được sản xuất hàng loạt để tung ra thị trường. Các thiết bị ngoại vi xuất hiện ngày càng nhiều, do đó các thao tác điều khiển máy tính và thiết bị ngoại vi ngày càng phức tạp hơn. Trước tình hình này nhu cầu cần có một hệ điều hành sử dụng chung trên tất cả các máy tính của nhà sản xuất và người sử dụng trở nên bức thiết hơn. Và hệ điều hành đã ra đời trong thời kỳ này.
Hệ điều hành ra đời nhằm điều phối, kiểm soát hoạt động của hệ thống và giải quyết các yêu cầu tranh chấp thiết bị. Hệ điều hành đầu tiên được viết bằng ngôn ngữ Assembly. Hệ điều hành xuất hiện khái niệm đa chương, khái niệm chia
sẻ thời gian và kỹ thuật Spool. Trong giai đoạn này cũng xuất hiện các hệ điều hành Multics và Unix.
I.1.2.d. Thế hệ 4 (từ 1980)
Máy tính cá nhân ra đời. Hệ điều hành MS_DOS ra đời gắn liền với máy tính IBM_PC. Hệ điều hành mạng và hệ điều hành phân tán ra đời trong thời kỳ này. ⮚ Trên đây chúng tôi không có ý định trình bày chi tiết, đầy đủ về lịch sử hình thành của hệ điều hành, mà chúng tôi chỉ muốn mượn các mốc thời gian về sự ra đời của các thế hệ máy tính để chỉ cho bạn thấy quá trình hình thành của hệ điều hành gắn liền với quá trình hình thành máy tính. Mục tiêu của chúng tôi trong mục này là muốn nhấn mạnh với các bạn mấy điểm sau đây:
∙ Các ngôn ngữ lập trình, đặc biệt là các ngôn ngữ lập trình cấp thấp, ra đời trước các hệ điều hành. Đa số các hệ điều hành đều được xây dựng từ ngôn ngữ lập trình cấp thấp trừ hệ điều hành Unix, nó được xây dựng từ C, một ngôn ngữ lập trình cấp cao.
∙ Nếu không có hệ điều hành thì việc khai thác và sử dụng máy tính sẽ khó khăn và phức tạp rất nhiều và không phải bất kỳ ai cũng có thể sử dụng máy tính được.
∙ Sự ra đời và phát triển của hệ điều hành gắn liền với sự phát triển của máy tính, và ngược lại sự phát triển của máy tính kéo theo sự phát triển của hệ điều hành. Hệ điều hành thực sự phát triển khi máy tính PC xuất hiện trên thị trường.
∙ Ngoài ra chúng tôi cũng muốn giới thiệu một số khái niệm như: hệ thống xử lý theo lô, hệ thống đa chương, hệ thống chia sẻ thời gian, kỹ thuật Spool, ..., mà sự xuất hiện của những khái niệm này đánh dấu một bước phát triển mới của hệ điều hành. Chúng ta sẽ làm rõ các khái niệm trên trong các chương sau của tài liệu này.
I.9. Một số khái niệm của hệ điều hành
I.2.6. Tiến trình (Process) và tiểu trình (Thread)
Tiến trình là một bộ phận của chương trình đang thực hiện. Tiến trình là đơn vị làm việc cơ bản của hệ thống, trong hệ thống có thể tồn tại nhiều tiến trình cùng hoạt động, trong đó có cả tiến trình của hệ điều hành và tiến trình của chương trình người sử dụng. Các tiến trình này có thể hoạt động đồng thời với nhau.
Để một tiến trình đi vào trạng thái hoạt động thì hệ thống phải cung cấp đầy đủ tài nguyên cho tiến trình. Hệ thống cũng phải duy trì đủ tài nguyên cho tiến trình trong suốt quá trình hoạt động của tiến trình.
Ở đây cần phân biệt sự khác nhau giữa tiến trình và chương trình, chương trình là một tập tin thụ động nằm trên đĩa, tiến trình là trạng thái động của chương
trình.
Các hệ điều hành hiện đại sử dụng mô hình đa tiểu trình, trong một tiến trình có thể có nhiều tiểu trình. Tiểu trình cũng là đơn vị xử lý cơ bản trong hệ thống, nó cũng xử lý tuần tự đoạn code của nó, nó cũng sở hữu một con trỏ lệnh, một tập các thanh ghi và một vùng nhớ stack riêng và các tiểu trình cũng chia sẻ thời gian xử lý của processor như các tiến trình.
Các tiểu trình trong một tiến trình chia sẻ một không gian địa chỉ chung, điều này có nghĩa các tiểu trình có thể chia sẻ các biến toàn cục của tiến trình, có thể truy xuất đến stack của tiểu trình khác trong cùng tiến trình. Như vậy với mô hình tiểu trình, trong hệ thống có thể tồn tại nhiều dòng xử lý cùng chia sẻ một không gian địa chỉ bộ nhớ, các dòng xử lý này hoạt động song song với nhau.
I.2.7. Bộ xử lý lệnh (Shell)
Shell là một bộ phận hay một tiến trình đặc biệt của hệ điều hành, nó có nhiệm vụ nhận lệnh của người sử dụng, phân tích lệnh và phát sinh tiến trình mới để thực hiện yêu cầu của lệnh, tiến trình mới này được gọi là tiến trình đáp ứng yêu cầu.
Shell nhận lệnh thông qua cơ chế dòng lệnh, đó chính là nơi giao tiếp giữa người sử dụng và hệ điều hành, mỗi hệ điều hành khác nhau có cơ chế dòng lệnh khác nhau, với MS_DOS đó là con trỏ lệnh và dấu nhắc hệ điều hành (C:\>_), với Windows 9x đó là nút Start\Run. Tập tin Command.Com chính là Shell của MS_DOS.
Trong môi trường hệ điều hành đơn nhiệm, ví dụ như MS_DOS, khi tiến trình đáp ứng yêu cầu hoạt động thì Shell sẽ chuyển sang trạng thái chờ, để chờ cho đến khi tiến trình đáp ứng yêu cầu kết thúc thì Shell trở lại trạng thái sẵn sàng nhận lệnh mới.
Trong môi trường hệ điều hành đa nhiệm, ví dụ như Windows 9x, sau khi phát sinh tiến trình đáp ứng yêu cầu và đưa nó vào trạng thái hoạt động thì Shell sẽ chuyển sang trạng thái sẵn sàng nhận lệnh mới, nhờ vậy Shell có khả năng khởi tạo nhiều tiến trình đáp ứng yêu cầu để nó hoạt động song song với nhau, hay chính xác hơn trong môi trường hệ điều hành đa nhiệm người sử dụng có thể khởi tạo nhiều chương trình để nó hoạt động đồng thời với nhau.
⮚ Chú ý: Hầu hết các ngôn ngữ lập trình đều hỗ trợ các công cụ để người sử dụng hay người lập trình có thể gọi shell ngay trong các ứng dụng của họ. Khi một ứng dụng cần gọi thực hiện một chương trình nào đó thì:
∙ Trong Assembly, các ứng dụng gọi hàm 4Bh/21h của MS_DOS. ∙ Trong Pascal, các ứng dụng gọi thủ tục Exec.
∙ Trong Visual Basic, các ứng dụng gọi hàm/ thủ tục Shell. Ví dụ dòng lệnh sau: Shell “C:\Windows\Notepad.exe” có thể gọi thực
hiện chương trình Notepad của Windows.
∙ Trong Windows 9x/ Windows NT, các ứng dụng gọi hàm ShellExecute.
I.2.8. Sự phân lớp hệ thống (System Layering)
Như đã biết, hệ điều hành là một hệ thống các chương trình bao quanh máy tính thực (vật lý) nhằm tạo ra một máy tính mở rộng (logic) đơn giản và dễ sử dụng hơn. Theo đó, khi khai thác máy tính người sử dụng chỉ cần tác động vào lớp vỏ bọc bên ngoài của máy tính, mọi sự giao tiếp giữa lớp vỏ bọc này với các chi tiết phần cứng bên trong đều do hệ điều hành thực hiện.
Mỗi người sử dụng khác nhau yêu cầu khai thác hệ điều hành ở những mức độ khác nhau. Người sử dụng thông thường chỉ cần một môi trường thuận lợi để họ thực hiện các ứng dụng, các lập trình viên cần có một môi trường lập trình tốt để họ có thể triển khai các ứng dụng, các chuyên viên lập trình hệ thống cần hệ điều hành cung cấp cho họ các công cụ để họ can thiệp sâu hơn vào hệ thống phần cứng máy tính, ... Để đáp ứng yêu cầu của nhiều đối tượng người sử dụng khác nhau hệ điều
Ngæåìi duìng
Ngæåìi láûp trçnh
Trçnh
æïng duûng
Caïc tiãûn êch
Hãû âiãöu haình
Pháön cæïng
Hình 1.1 Sự phân lớp hệ thống
Ngæåìi thiãút kãú hãû âiãöu haình
hành thực hiện phân lớp các chương trình bao quanh máy tính. Các hệ thống như vậy được gọi là hệ thống phân lớp. Hình vẽ 1.1 ở trên minh hoạ cho một hệ thống phân lớp.
Ta có thể hình dung một hệ thống phân lớp được tổ chức như sau: ∙ Trong cùng là hệ điều hành.
∙ Tiếp theo là các ngôn ngữ lập trình
∙ ...
∙ Ngoài cùng là các chương trình ứng dụng .
Người sử dụng tác động vào lớp trong cùng sẽ gặp nhiều khó khăn hơn khi tác động vào lớp ngoài cùng.
I.2.9. Tài nguyên hệ thống (System Resources)
Tài nguyên hệ thống là những tồn tại về mặt vật lý tại một thời điểm nhất định hoặc tại mọi thời điểm, và nó có khả năng tác động đến hiệu suất của hệ thống. Một cách tổng quát có thể chia tài nguyên của hệ thống thành hai loại cơ bản:
∙ Tài nguyên không gian: là các không gian lưu trữ của hệ thống như đĩa, bộ nhớ chính, quan trọng nhất là không gian bộ nhớ chính, nơi lưu trữ các chương trình đang được CPU thực hiện.
∙ Tài nguyên thời gian: chính là thời gian thực hiện lệnh của processor và thời gian truy xuất dữ liệu trên bộ nhớ.
⮚ Sau đây là một vài tài nguyên hệ thống:
❑ Bộ nhớ: Đặc trưng cơ bản của bộ nhớ là thời gian truy cập trực tiếp, thời gian truy cập tuần tự, và dung lượng nhớ. Bộ nhớ được gọi là thực hiện nếu processor có thể thực hiện một câu lệnh trong nó, loại bộ nhớ này có thời gian truy cập trực tiếp và tuần tự là như nhau. Bộ nhớ trong (RAM) của PC là bộ nhớ thực hiện và nó được quản lý bởi hệ thống.
Khi sử dụng bộ nhớ ta cần phân biệt 2 khái niệm: bộ nhớ và truy cập tới bộ nhớ. Bộ nhớ chỉ vùng vật lý chứa dữ liệu, truy cập bộ nhớ là quá trình tìm đến dữ liệu trên bộ nhớ. Có thể xem đây là 2 loại tài nguyên khác nhau vì chúng tồn tại độc lập với nhau.
❑ Processor: Là tài nguyên quan trọng nhất của hệ thống, nó được truy cập ở mức câu lệnh và chỉ có nó mới làm cho câu lệnh thực hiện hay chỉ có Processor mới đưa tiến trình vào trạng thái hoạt động. Trong thực tế khi xem xét về processor người ta chỉ chú ý đến thời gian xử lý của processor.
❑ Tài nguyên ảo/ tài nguyên logic (Virtual Resources): Là loại tài nguyên cung cấp cho chương trình người sử dụng dưới dạng đã được biến đổi, nó chỉ xuất hiện khi hệ thống cần tới nó hoặc khi hệ thống tạo ra nó và nó sẽ tự động mất đi khi hệ thống kết thúc hay chính xác hơn là khi tiến trình gắn với nó đã kết thúc. Tài nguyên ảo có thể là: Đĩa ảo trong môi trường MS_DOS. Điều khiển in trong môi trường mạng của Windows 9x/NT. Nội dung thư mục Spool trong Windows 9x.
⮚ Trên khía cạnh cấp phát tài nguyên cho các tiến trình đang hoạt động đồng thời thì tài nguyên hệ thống được chia thành 2 loại:
❑ Tài nguyên phân chia được: là những tài nguyên mà tại một thời điểm nó có thể cấp phát cho nhiều tiến trình khác nhau, các tiến trình song song có thể đồng thời sử dụng các tài nguyên này. Bộ nhớ chính và Processor là 2 tài
nguyên phân chia được điển hình nhất, bởi tại một thời điểm có thể có nhiều tiến trình cùng chia nhau sử dụng không gian lưu trữ của bộ nhớ chính và có thể có nhiều tiến trình thay nhau sử dụng thời gian xử lý của processor.
❑ Tài nguyên không phân chia được: là những tài nguyên mà tại một thời điểm nó chỉ có thể cấp phát cho một tiến trình duy nhất. Máy in là một tài nguyên không phân chia được điển hình nhất.
Vấn đề đặt ra đối với hệ điều hành là phải biến các tài nguyên không phân chia được thành những tài nguyên phân chia được, theo một cách nào đó, để cấp phát cho các tiến trình khi nó có yêu cầu, đặc biệt là các tiến trình hoạt động đồng thời với nhau. Các hệ điều hành đa nhiệm đã cài đặt thành công mục tiêu này. Như
chúng ta đã thấy trong môi trường Windows 9x/ NT có thể có nhều tiến trình/ nhiều người sử dụng khác nhau đồng thời sử dụng một máy in.
Ngoài ra hệ điều hành còn phải giải quyết vấn đề tranh chấp tài nguyên giữa các tiến trình đồng thời khi yêu cầu phục vụ của các tiến trình này vượt quá khả năng cấp phát của một tài nguyên kể cả đó là tài nguyên phân chia được.
I.2.10. Lời gọi hệ thống (System Calls)
Để tạo môi trường giao tiếp giữa chương trình của người sử dụng và hệ điều hành, hệ điều hành đưa ra các lời gọi hệ thống. Chương trình của người sử dụng dùng các lời gọi hệ thống để liên lạc với hệ điều hành và yêu cầu các dịch vụ từ hệ điều hành.
Mỗi lời gọi hệ thống tương ứng với một thủ tục trong thư viện của hệ điều hành, do đó chương trình của người sử dụng có thể gọi thủ tục để thực hiện một lời gọi hệ thống. Lời gọi hệ thống còn được thiết dưới dạng các câu lệnh trong các ngôn ngữ lập trình cấp thấp. Lệnh gọi ngắt trong hợp ngữ (Int), và thủ tục gọi hàm API trong windows được xem là một lời gọi hệ thống.
Lời gọi hệ thống có thể được chia thành các loại: quản lý tiến trình, thao tác trên tập tin, thao tác trên thiết bị vào/ ra, thông tin liên tiến trình, ... Sau đây là một số lời gọi hệ thống của hệ điều hành MS_DOS:
∙ S = Load_and_exec(processname): tạo tiến trình con và thực hiện nó. ∙ Fd = Open(filename, mode): mở file để đọc hoặc/và ghi.
∙ N = Write(Fd, buffer, nbyte): ghi dữ liệu từ đệm vào file.
∙ Addr = alloc_memory(nbyte): cấp phát một khối nhớ
∙ Keep_pro(mem_size, status): kết thúc và thường trú chương trình. Chú ý: Cần phải phân biệt sự khác nhau giữa Shell và System Call. Shell tạo môi trường giao tiếp giữa người sử dụng và hệ điều hành, System Call tạo môi trường giao tiếp giữa chương trình người sử dụng và hệ điều hành.
I.10. Hệ điều hành và phân loại hệ điều hành
I.3.3. Hệ điều hành là gì?
Khó có một khái niệm hay định nghĩa chính xác về hệ điều hành, vì hệ điều hành là một bộ phận được nhiều đối tượng khai thác nhất, họ có thể là người sử dụng thông thường, có thể là lập trình viên, có thể là người quản lý hệ thống và tùy theo mức độ khai thác hệ điều hành mà họ có thể đưa ra những khái niện khác nhau về nó. Ở đây ta xem xét 3 khái niệm về hệ điều hành dựa trên quan điểm của người khai thác hệ thống máy tính:
❑ Khái niệm 1: Hệ điều hành là một hệ thống mô hình hoá, mô phỏng hoạt động của máy tính, của người sử dụng và của lập trình viên, hoạt động trong chế độ đối thoại nhằm tạo môi trường khai thác thuận lợi hệ thống máy tính và quản lý tối ưu tài nguyên của hệ thống.
❑ Khái niệm 2: Hệ điều hành là hệ thống chương trình với các chức năng giám sát, điều khiển việc thực hiện các chương trình của người sử dụng, quản lý và phân chia tài nguyên cho nhiều chương trình người sử dụng đồng thời sao cho việc khai thác chức năng của hệ thống máy tính của người sử dụng là thuận lợi và hiệu quả nhất.
❑ Khái niệm 3: Hệ điều hành là một chương trình đóng vai trò như là giao diện giữa người sử dụng và phần cứng máy tính, nó điều khiển việc thực hiện của tất cả các loại chương trình. Khái niệm này rất gần với các hệ điều hành đang sử dụng trên các máy tính hiện nay.
Từ các khái niệm trên chúng ta có thể thấy rằng: Hệ điều hành ra đời, tồn tại và phát triển là để giải quyết vấn đề sử dụng máy tính của người sử dụng, nhằm giúp người sử dụng khai thác hết các chức năng của phần cứng máy tính mà cụ thể là giúp người sử dụng thực hiện được các chương trình của họ trên máy tính.
I.3.4. Phân loại hệ điều hành
Có nhiều cách khác nhau để phân loại hệ điều hành, ở đây chúng tôi dựa vào cách mà hệ điều hành thực hiện các công việc, các tác vụ, các tiến trình của người sử dụng để phân loại hệ điều hành.
I.3.2.a. Hệ điều hành xử lý theo lô đơn giản
Hệ điều hành loại này thực hiện các tác vụ lần lượt theo những chỉ thị đã được xác định trước. Khi một tác vụ chấm dứt thì hệ thống sẽ tự động thực hiện tác vụ tiếp theo mà không cần sự can thiệp từ bên ngoài, do đó hệ thống đạt tốc độ thực hiện cao. Để thực hiện được điều này hệ điều hành phải có bộ phận giám sát thường trực để giám sát việc thực hiện của các tác vụ trong hệ thống, bộ phận này thường trú trong bộ nhớ chính.Mäi træåìng ngæåìi sæí duûng
Nháûp taïc vuû
Mäi træåìng maïy tênh
Trong hệ điều hành này khi hệ thống cần thực hiện một tác vụ thì nó phải lưu chương trình và dữ liệu của các tác vụ vào hành đợi các công việc, sau đó sẽ thực hiện lần lượt từng bộ chương trình và dữ liệu của tác vụ tương ứng trong hàng đời và cho ra lần lượt các kết quả. Hình 1.2 ở trên minh họa cho sự hoạt động của hệ thống theo lô đa chương.
⮚ Với cách tổ chức hàng đợi tác vụ, thì hệ thống không thể thay đổi chương trình và dữ liệu của các tác vụ ngay cả khi chúng còn nằm trong hàng đợi, đây là một hạn chế. Mặt khác trong quá trình thực hiện tác vụ nếu tác vụ chuyển sang truy xuất trên thiết bị vào/ra thì processor rơi vào trạng thái chờ điều này gây lãng phí thời gian xử lý của processor.
I.3.2.b. Hệ điều hành xử lý theo lô đa chương
Một trong những hạn chế của hệ điều hành xử lý theo lô đơn giản là lãng phí thời gian xử lý của processor khi tác vụ hiện tại truy xuất đến thiết bị vào/ra. Hệ điều hành xử lý theo lô đa chương sẽ khắc phục hạn chế này.
Hệ điều hành loại này có khả năng thực hiện nhiều tác vụ, nhiều chương trình đồng thời. Khi cần thực hiện nhiều tác vụ đồng thời hệ điều hành sẽ nạp một phần code và data của các tác vụ vào bộ nhớ (các phần còn lại sẽ được nạp sau tại thời điểm thích hợp) và tất cả đều ở trạng thái sẵn sàng thực hiện, sau đó hệ điều hành bắt đầu thực hiện một tác vụ nào đó, nhưng khi tác vụ đang thực hiện cần truy xuất thiết bị vào/ra thì processor sẽ được chuyển sang thực hiện các tác vụ khác, và cứ như thế hệ điều hành tổ chức chuyển hướng processor để thực hiện hết các phần tác vụ trong bộ nhớ cũng như các tác vụ mà hệ thống yêu cầu.
⮚ Hệ điều hành loại này mang lại hai ưu điểm đó là tiết kiệm được bộ nhớ, vì không nạp hết code và data của các tác vụ vào bộ nhớ, và hạn chế thời gian rỗi của processor. Tuy nhiên nó phải chi phí cao cho việc lập lịch processor, tức là khi có được processor hệ điều hành phải xem xét nên chuyển nó cho tác vụ nào trong số các tác vụ đang ở trạng thái sẵn sàng. Ngoài ra hệ điều hành còn phải giải quyết việc chia sẻ bộ nhớ chính cho các tác vụ khác nhau. Hệ điều hành MS_DOS là hệ điều hành đơn nhiệm, đa chương.
I.3.2.c. Hệ điều hành chia sẻ thời gian
Khái niệm chia sẻ thời gian ra đời đã đánh dấu một bước phát triển mới của hệ điều hành trong việc điều khiển các hệ thống đa người dùng. Chia sẻ thời gian ở đây chính là chia sẻ thời gian xử lý của processor cho các tác vụ, các tiến trình đang ở trong trạng thái sẵn sàng thực hiện.
Nguyên tắc của hệ điều hành chia sẻ thời gian tương tự như trong hệ điều hành xử lý theo lô đa chương nhưng việc chuyển processor từ tác vu, tiến trình này sang tác vụ, tiến trình khác không phụ thuộc vào việc tác vụ, tiến trình hiện tại có truy xuất đến thiết bị vào/ra hay không mà chỉ phụ thuộc vào sự điều phối processor của hệ điều hành. Công việc điều phối processor của hệ điều hành rất phức tạp phụ thuộc vào nhiều yếu tố khác nhau, chúng ta sẽ đề cập đến vấn đề này trong chương sau của tài liệu này.
Trong hệ điều hành này thời gian chuyển đổi processor giữa các tác vụ là rất nhỏ nên ta có cảm giác các tác vụ thực hiện song song với nhau. Với hệ điều hành này người sử dụng có thể yêu cầu hệ điều hành thực hiện nhiều chương trình, tiến trình, tác vụ đồng thời với nhau.
⮚ Hệ điều hành chia sẻ thời gian là mở rộng logic của hệ điều hành đa chương và nó thường được gọi là hệ điều hành đa nhiệm (Multitasking). Hệ điều hành Windows 9x/NT là các hệ điều hành đa nhiệm.
I.3.2.d.Hệ điều hành đa vi xử lý
Là các hệ điều hành dùng để điều khiển sự hoạt động của các hệ thống máy tính có nhiều vi xử lý. Các hệ điều hành đa vi xử lý (multiprocessor) gồm có 2 loại: ❑ Đa xử lý đối xứng (SMP: symmetric): Trong hệ thống này vi xử lý nào cũng có thể chạy một loại tiểu trình bất kỳ, các vi xử lý giao tiếp với nhau thông qua một bộ nhớ dùng chung. Hệ SMP cung cấp một cơ chế chịu lỗi và khả năng cân bằng tải tối ưu hơn, vì các tiểu trình của hệ điều hành có thể chạy trên bất kỳ vi xử lý nào nên nguy cơ xảy ra tình trạng tắc nghẽn ở CPU giảm đi đáng kể. Vấn đề đồng bộ giữa các vi xử lý được đặt lên hàng đầu khi thiết kế hệ điều hành cho hệ thống SMP. Hệ điều hành Windows NT, hệ điều hành Windows 2000 là các hệ điều hành đa xử lý đối xứng.
❑ Đa xử lý bất đối xứng (ASMP: asymmetric): Trong hệ thống này hệ điều hành dành ra một hoặc hai vi xử lý để sử dụng riêng, các vi xử lý còn lại dùng để điều khiển các chương trình của người sử dụng. Hệ ASMP đơn giản hơn nhiều so với hệ SMP, nhưng trong hệ này nếu có một vi xử lý trong các vi xử lý dành riêng cho hệ điều hành bị hỏng thì hệ thống có thể ngừng hoạt động.
I.3.2.e. Hệ điều hành xử lý thời gian thực
Hệ điều hành này khắc phục nhược điểm của hệ điều hành xử lý theo lô, tức là nó có khả năng cho kết quả tức thời, chính xác sau mỗi tác vụ.
Trong hệ điều hành này các tác vụ cầu thực hiện không được đưa vào hàng đợi mà được xử lý tức thời và trả lại ngay kết quả hoặc thông báo lỗi cho người sử dụng có yêu cầu. Hệ điều hành này hoạt động đòi hỏi sự phối hợp cao giữa phần mềm và phần cứng.
I.3.2.f.Hệ điều hành mạng
Là các hệ điều hành dùng để điều khiển sự hoạt động của mạng máy tính. Ngoài các chức năng cơ bản của một hệ điều hành, các hệ điều hành mạng còn phải thực hiện việc chia sẻ và bảo vệ tài nguyên của mạng. Hệ điều hành Windows 9x/NT, Windows 200, Linux, là các hệ điều hành mạng máy tính.
⮚ Tóm lại: Qua sự phân loại hệ điều hành ở trên ta có thể thấy được quá trình phát triển (evolution) của hệ điều hành. Để khắc phục hạn chế về lãng phí thời gian xử lý của processor trong hệ điều hành theo lô thì hệ điều hành theo lô đa chương ra đời. Để khai thác tối đa thời gian xử lý của processor và tiết kiệm hơn nữa không gian bộ nhớ chính hệ điều hành chia sẻ thời gian ra đời. Chia sẻ thời gian xử lý của processor kết hợp với chia sẻ không gian bộ nhớ chính đã giúp cho hệ điều hành có thể đưa vào bộ nhớ chính nhiều chương trình, tiến trình hơn và các chương trình, tiến trình này có thể hoạt động đồng thời với nhau, nhờ đó mà hiệu suất của hệ thống tăng lên, và cũng từ đây khái niệm hệ điều hành đa chương ra đời. Hệ điều hành đa xử lý và hệ điều hành mạng được phát triển dựa trên hệ điều hành đa nhiệm. Hệ điều hành thời gian thực ra đời là để khắc phục hạn chế của hệ điều hành theo lô và điều khiển các hệ thống thời gian thực. Từ đây chúng ta rút ra một điều rằng: các hệ điều hành ra đời sau luôn tìm cách khắc phục các hạn chế của hệ điều hành trước đó và phát triển nhiều hơn nữa để đáp ứng yêu cầu ngày càng cao của của người sử dụng và chương trình người sử dụng, cũng như khai thác tối đa các chức năng của phần cứng máy tính để nâng cao hiệu suất của hệ thống. Nhưng chức năng của hệ điều hành càng cao thì chi phí cho nó cũng tăng theo và cấu trúc của hệ điều hành cũng sẽ phức tạp hơn.
Hệ điều hành Windows NT và hệ điều hành Windows 2000 là các hệ điều hành mạnh, nó có đầy đủ các chức năng của các loại hệ điều hành, do đó WindowsNT/2000 chứa rất nhiều thành phần với một cấu trúc khá phức tạp.
I.11. Thành phần và cấu trúc của hệ điều hành
Hệ điều hành là một hệ thống chương trình lớn, thực hiện nhiều nhiệm vụ khác nhau, do đó các nhà thiết kế thường chia hệ điều hành thành nhiều thành phần, mỗi thành phần đảm nhận một nhóm các nhiệm vụ nào đó, các nhiệm vụ này có liên quan với nhau. Cách phân chia nhiệm vụ cho mỗi thành phần, cách kết nối các thành phần lại với nhau để nó thực hiện được một nhiệm vụ lớn hơn khi cần và cách gọi các thành phần này khi cần nó thực hiện một nhiệm vụ nào đó, ... , tất cả các phương thức trên tạo nên cấu trúc của hệ điều hành.
I.4.3. Các thành phần của hệ điều hành
I.4.1.a.Thành phần quản lý tiến trình
Hệ điều hành phải có nhiệm vụ tạo lập tiến trình và đưa nó vào danh sách quản lý tiến trình của hệ thống. Khi tiến trình kết thúc hệ điều hành phải loại bỏ tiến trình ra khỏi danh sách quản lý tiến trình của hệ thống.
Hệ điều hành phải cung cấp đầy đủ tài nguyên để tiến trình đi vào hoạt động và phải đảm bảo đủ tài nguyên để duy trì sự hoạt động của tiến trình cho đến khi tiến trình kết thúc. Khi tiến trình kết thúc hệ điều hành phải thu hồi những tài nguyên mà hệ điều hành đã cấp cho tiến trình.
Trong quá trình hoạt động nếu vì một lý do nào đó tiến trình không thể tiếp tục hoạt động được thì hệ điều hành phải tạm dừng tiến trình, thu hồi tài nguyên mà tiến trình đang chiếm giữ, sau đó nếu điều kiện thuận lợi thì hệ điều hành phải tái kích hoạt tiến trình để tiến trình tiếp tục hoạt động cho đến khi kết thúc.
Trong các hệ thống có nhiều tiến trình hoạt động song song hệ điều hành phải giải quyết vấn đề tranh chấp tài nguyên giữa các tiến trình, điều phối processor cho các tiến trình, giúp các tiến trình trao đổi thông tin và hoạt động đồng bộ với nhau, đảm bảo nguyên tắc tất cả các tiến trình đã được khởi tạo phải được thực hiện và kết thúc được.
⮚ Tóm lại, bộ phận quản lý tiến trình của hệ điều hành phải thực hiện những nhiệm vụ sau đây:
∙ Tạo lập, hủy bỏ tiến trình.
∙ Tạm dừng, tái kích hoạt tiến trình.
∙ Tạo cơ chế thông tin liên lạc giữa các tiến trình.
∙ Tạo cơ chế đồng bộ hóa giữa các tiến trình.
I.4.1.b.Thành phần quản lý bộ nhớ chính
Bộ nhớ chính là một trong những tài nguyên quan trọng của hệ thống, đây là thiết bị lưu trữ duy nhất mà CPU có thể truy xuất trực tiếp được.
Các chương trình của người sử dụng muốn thực hiện được bởi CPU thì trước hết nó phải được hệ điều hành nạp vào bộ nhớ chính, chuyển đổi các địa chỉ sử dụng trong chương trình thành những địa chỉ mà CPU có thể truy xuất được.
Khi chương trình, tiến trình có yêu cầu được nạp vào bộ nhớ thì hệ điều hành phải cấp phát không gian nhớ cho nó. Khi chương trình, tiến trình kết thúc thì hệ điều hành phải thu hồi lại không gian nhớ đã cấp phát cho chương trình, tiến trình trước đó.
Trong các hệ thống đa chương hay đa tiến trình, trong bộ nhớ tồn tại nhiều chương trình/ nhiều tiến trình, hệ điều hành phải thực hiện nhiệm vụ bảo vệ các
vùng nhớ đã cấp phát cho các chương trình/ tiến trình, tránh sự vi phạm trên các vùng nhớ của nhau.
⮚ Tóm lại, bộ phận quản lý bộ nhớ chính của hệ điều hành thực hiện những nhiệm vụ sau:
∙ Cấp phát, thu hồi vùng nhớ.
∙ Ghi nhận trạng thái bộ nhớ chính.
∙ Bảo vệ bộ nhớ.
∙ Quyết định tiến trình nào được nạp vào bộ nhớ.
I.4.1.c. Thành phần quản lý xuất/ nhập
Một trong những mục tiêu của hệ điều hành là giúp người sử dụng khai thác hệ thống máy tính dễ dàng và hiệu quả, do đó các thao tác trao đổi thông tin trên thiết bị xuất/ nhập phải trong suốt đối với người sử dụng.
Để thực hiện được điều này hệ điều hành phải tồn tại một bộ phận điều khiển thiết bị, bộ phận này phối hợp cùng CPU để quản lý sự hoạt động và trao đổi thông tin giữa hệ thống, chương trình người sử dụng và người sử dụng với các thiết bị xuất/ nhập.
Bộ phận điều khiển thiết bị thực hiện những nhiệm vụ sau:
∙ Gởi mã lệnh điều khiển đến thiết bị: Hệ điều hành điều khiển các thiết bị bằng các mã điều khiển, do đó trước khi bắt đầu một quá trình trao đổi dữ liệu với thiết bị thì hệ điều hành phải gởi mã điều khiển đến thiết bị. ∙ Tiếp nhận yêu cầu ngắt (Interrupt) từ các thiết bị: Các thiết bị khi cần trao đổi với hệ thống thì nó phát ra một tín hiệu yêu cầu ngắt, hệ điều hành tiếp nhận yêu cầu ngắt từ các thiết bị, xem xét và thực hiện một thủ tục để đáp ứng yêu cầu tù các thiết bị.
∙ Phát hiện và xử lý lỗi: quá trình trao đổi dữ liệu thường xảy ra các lỗi như: thiết bị vào ra chưa sẵn sàng, đường truyền hỏng, ... do đó hệ điều hành phải tạo ra các cơ chế thích hợp để phát hiện lỗi sớm nhất và khắc phục các lỗi vừa xảy ra nếu có thể.
I.4.1.d.Thành phần quản lý bộ nhớ phụ (đĩa)
Không gian lưu trữ của đĩa được chia thành các phần có kích thước bằng nhau được gọi là các block, khi cần lưu trữ một tập tin trên đĩa hệ điều hành sẽ cấp cho tập tin một lượng vừa đủ các block để chứa hết nội dung của tập tin. Block cấp cho tập tin phải là các block còn tự do, chưa cấp cho các tập tin trước đó, do đó sau khi thực hiện một thao tác cấp phát block hệ điều hành phải ghi nhận trạng thái của các block trên đĩa, đặc biệt là các block còn tự do để chuẩn bị cho các quá trình cấp block sau này.
Trong quá trình sử dụng tập tin nội dung của tập tin có thể thay đổi (tăng, giảm), do đó hệ điều hành phải tổ chức cấp phát động các block cho tập tin. Để ghi/đọc nội dung của một block thì trước hết phải định vị đầu đọc/ ghi đến block đó. Khi chương trình của người sử dụng cần đọc nội dung của một đãy các block không liên tiếp nhau, thì hệ điều hành phải chọn lựa nên đọc block nào trước, nên đọc theo thứ tự nào,..., dựa vào đó mà hệ điều hành di chuyển đầu đọc đến các block thích hợp, nhằm nâng cao tốc độ đọc dữ liệu trên đĩa. Thao tác trên được gọi là lập lịch cho đĩa.
⮚ Tóm lại, bộ phận quản lý bộ nhớ phụ thực hiện những nhiệm vụ sau: ∙ Quản lý không gian trống trên đĩa.
∙ Định vị lưu trữ thông tin trên đĩa.
∙ Lập lịch cho vấn đề ghi/ đọc thông tin trên đĩa của đầu từ.
I.4.1.e.Thành phần quản lý tập tin
Máy tính có thể lưu trữ thông tin trên nhiều loại thiết bị lưu trữ khác nhau, mỗi thiết bị lại có tính chất và cơ chế tổ chức lưu trữ thông tin khác nhau, điều này gây khó khăn cho người sử dụng. Để khắc phục điều này hệ điều hành đưa ra khái niệm
đồng nhất cho tất cả các thiết bị lưu trữ vật lý, đó là tập tin (file). Tập tin là đơn vị lưu trữ cơ bản nhất, mỗi tập tin có một tên riêng. Hệ điều hành phải thiết lập mối quan hệ tương ứng giữa tên tập tin và thiết bị lưu trữ chứa tập tin. Theo đó khi cần truy xuất đến thông tin đang lưu trữ trên bất kỳ thiết bị lưu trữ nào người sử dụng chỉ cần truy xuất đến tập tin tương ứng thông qua tên của nó, tất cả mọi việc còn lại đều do hệ điều hành thực hiện.
Trong hệ thống có nhiều tiến trình đồng thời truy xuất tập tin hệ điều hành phải tạo ra những cơ chế thích hợp để bảo vệ tập tin trách việc ghi/ đọc bất hợp lệ trên tập tin.
⮚ Tóm lại: Như vậy bộ phận quản lý tập tin của hệ điều hành thực hiện những nhiệm vụ sau:
∙ Tạo/ xoá một tập tin/ thư mục.
∙ Bảo vệ tập tin khi có hiện tượng truy xuất đồng thời.
∙ Cung cấp các thao tác xử lý và bảo vệ tập tin/ thư mục.
∙ Tạo mối quan hệ giữa tập tin và bộ nhớ phụ chứa tập tin.
∙ Tạo cơ chế truy xuất tập tin thông qua tên tập tin.
I.4.1.f. Thành phần thông dịch lệnh
Đây là bộ phận quan trọng của hệ điều hành, nó đóng vai trò giao tiếp giữa hệ điều hành và người sử dụng. Thành phần này chính là shell mà chúng ta đã biết ở trên. Một số hệ điều hành chứa shell trong nhân (kernel) của nó, một số hệ điều hành
khác thì shell được thiết kế dưới dạng một chương trình đặc biệt. I.4.1.g. Thành phần bảo vệ hệ thống
Trong môi trường hệ điều hành đa nhiệm có thể có nhiều tiến trình hoạt động đồng thời, thì mỗi tiến trình phải được bảo vệ để không bị tác động, có chủ ý hay không chủ ý, của các tiến trình khác. Trong trường hợp này hệ điều hành cần phải có các cơ chế để luôn đảm bảo rằng các File, Memory, CPU và các tài nguyên khác mà hệ điều hành đã cấp cho một chương trình, tiến trình thì chỉ có chương trình tiến trình đó được quyền tác động đến các thành phần này.
Nhiệm vụ trên thuộc thành phần bảo vệ hệ thống của hệ điều hành. Thành phần này điều khiển việc sử dụng tài nguyên, đặc biệt là các tài nguyên dùng chung, của các tiến trình, đặc biệt là các tiến trình hoạt động đồng thời với nhau, sao cho không xảy ra sự tranh chấp tài nguyên giữa các tiến trình hoạt đồng đồng thời và không cho phép các tiến trình truy xuất bất hợp lệ lên các vùng nhớ của nhau.
⮚ Ngoài ra các hệ điều hành mạng, các hệ điều hành phân tán hiện nay còn có thêm thành phần kết nối mạng và truyền thông..
⮚ Để đáp ứng yêu cầu của người sử dụng và chương trình người sử dụng các nhiệm vụ của hệ điều hành được thiết kế dưới dạng các dịch vụ: ∙ Thi hành chương trình: hệ điều hành phải có nhiệm vụ nạp chương trình của người sử dụng vào bộ nhớ, chuẩn bị đầy đủ các điều kiện về tài nguyên để chương trình có thể chạy được và kết thúc được, có thể kết thúc bình thường hoặc kết thúc do bị lỗi. Khi chương trình kết thúc hệ điều hành phải thu hồi tài nguyên đã cấp cho chương trình và ghi lại các thông tin mà chương trình đã thay đổi trong quá trình chạy (nếu có).
∙ Thực hiện các thao tác xuất nhập dữ liệu: Khi chương trình chạy nó có thể yêu cầu xuất nhập dữ liệu từ một tập tin hoặc từ một thiết bị xuất nhập nào đó, trong trường hợp này hệ điều hành phải hỗ trợ việc xuất nhập dữ liệu cho chương trình, phải nạp được dữ liệu mà chương trình cần vào bộ nhớ.
∙ Thực hiện các thao tác trên hệ thống tập tin: Hệ điều hành cần cung cấp các công cụ để chương trình dễ dàng thực hiện các thao tác đọc ghi trên các tập tin, các thao tác này phải thực sự an toàn, đặc biệt là trong môi trường đa nhiệm.
∙ Trao đổi thông tin giữa các tiến trình: Trong môi trường hệ điều hành đa nhiệm, với nhiều tiến trình hoạt động đồng thời với nhau, một tiến trình có thể trao đổi thông tin với nhiều tiến trình khác, hệ điều hành phải cung cấp các dịch vụ cần thiết để các tiến trình có thể trao đổi thông tin với nhau và phối hợp cùng nhau để hoàn thành một tác vụ nào đó.
∙ Phát hiện và xử lý lỗi: Hệ điều hành phải có các công cụ để chính hệ
điều hành và để hệ điều hành giúp chương trình của người sử dụng phát hiện các lỗi do hệ thống (CPU, Memory, I/O device, Program) phát sinh. Hệ điều hành cũng phải đưa ra các dịch vụ để xử lý các lỗi sao cho hiệu quả nhất.
I.4.4. Các cấu trúc của hệ điều hành
I.4.2.a. Hệ thống đơn khối (monolithic systems)
Trong hệ thống này hệ điều hành là một tập hợp các thủ tục, mỗi thủ tục có thể gọi thực hiện một thủ tục khác bất kỳ lúc nào khi cần thiết.
Hệ thống đơn khối thường được tổ chức theo nhiều dạng cấu trúc khác nhau: ❑ Sau khi biên dịch tất cả các thủ tục riêng hoặc các file chứa thủ tục của hệ điều hành được liên kết lại với nhau và được chứa vào một file được gọi là file đối tượng, trong file đối tượng này còn chứa cả các thông tin về sự liên kết của các thủ tục.
❑ Sau khi biên dịch các thủ tục của hệ điều hành không được liên kết lại, mà hệ thống chỉ tạo ra file hoặc một bảng chỉ mục để chứa thông tin của các thủ tục hệ điều hành, mỗi phần tử trong bảng chỉ mục chứa một con trỏ trỏ tới thủ tục tương ứng, con trỏ này dùng để gọi thủ tục khi cần thiết. Ta có thể xem cách gọi ngắt (Interrupt) trong ngôn ngữ lập trình cấp thấp và cách thực hiện đáp ứng ngắt dựa vào bảng vector ngắt trong MS_DOS là một ví dụ cho cấu trúc này.
Hình vẽ sau đây minh họa cho việc đáp ứng một lời gọi dịch vụ từ chương trình của người sử dụng dựa vào bảng chỉ mục.
C/ trçnh ngæåìi sæí duûng 2
Chæång trçnh
Goüi Kernel
C/ trçnh ngæåìi sæí duûng 1
ngæåìi sæí duûng chaûy
Main memory①④ ③
Thuí tuûc Dëch vuû
trong Uer mode
Hãû âiãöu haình chaûy trong
Kernel mode
②
Baíng mä taí
Hçnh 1.3: Så âäö thæûc hiãûn låìi goüi hãû thäúng
Trong đó:
1. Chương trình của người sử dụng gởi yêu cầu đến Kernel. 2. Hệ điều hành kiểm tra yêu cầu dịch vụ.
3. Hệ điều hành xác định (vị trí) và gọi thủ tục dịch vụ tương ứng. 4. Hệ điều hành trả điều khiển lại cho chương trình người sử dụng. Sau đây là một cấu trúc đơn giản của hệ thống đơn khối, trong cấu trúc này các thủ tục được chia thành 3 lớp:
1. Một chương trình chính (chương trình của người sử dụng) gọi đến một thủ tục dịch vụ của hệ điều hành. Lời gọi này được gọi là lời gọi hệ thống. 2. Một tập các thủ tục dịch vụ (service) để đáp ứng những lời gọi hệ thống từ các chương trình người sử dụng.
3. Một tập các thủ tục tiện ích (utility) hỗ trợ cho các thủ tục dịch trong việc thực hiện cho các lời gọi hệ thống.
Trong cấu trúc này mỗi lời gọi hệ thống sẽ gọi một thủ tục dịch vụ tương ứng. Thủ tục tiện ích thực hiện một vài điều gì đó mà thủ tục dịch vụ cần, chẳng hạn như nhận dữ liệu từ chương trình người sử dụng. Các thủ tục của hệ điều hành được chia vào 3 lớp theo như hình vẽ dưới đây.
Thuí tuûc chênh
Thuí tuûc dëch vuû
Thuí tuûc tiãûn êch
Hçnh 1.4: Cáúu truïc âån giaín cuía mäüt monolithic system
Nhận xét:
∙ Với cấu trúc này chương trình của người sử dụng có thể truy xuất trực tiếp đến các chi tiết phần cứng bằng cách gọi một thủ tục cấp thấp, điều này gây khó khăn cho hệ điều hành trong việc kiểm soát và bảo vệ hệ thống.
∙ Các thủ tục dịch vụ mang tính chất tỉnh, nó chỉ hoạt động khi được gọi bởi chương trình của người sử dụng, điều này làm cho hệ điều hành thiếu chủ động trong việc quản lý môi trường.
I.4.2.b. Các hệ thống phân lớp (Layered Systems)
Hệ thống được chia thành một số lớp, mỗi lớp được xây dựng dựa vào lớp bên trong. Lớp trong cùng thường là phần cứng, lớp ngoài cùng là giao diện với người sử dụng.
Mỗi lớp là một đối tượng trừu tượng, chứa dựng bên trong nó các dữ liệu và thao tác xử lý dữ liệu đó. Lớp n chứa dựng một cấu trúc dữ liệu và các thủ tục có thể được gọi bởi lớp n+1 hoặc ngược lại có thể gọi các thủ tục ở lớp n-1.
Ví dụ về một hệ điều hành phân lớp:
Lớp 5: Chương trình ứng dụng
Lớp 4: Quản lý bộ đệm cho các thiết bị xuất nhập
Lớp 3: Trình điều khiển thao tác console
Lớp 2: Quản lý bộ nhớ
Lớp 1: Điều phối processor
Lớp 0: Phần cứng hệ thống
Hình vẽ 1.5 sau đây cho ta thấy cấu trúc phân lớp trong hệ điều hành Unix. Nhận xét:
∙ Khi xây dựng hệ điều hành theo hệ thống này các nhà thiết kế gặp khó khăn trong việc xác định số lượng lớp, thứ tự và chức năng của mỗi lớp.
Giao diãûn
Ngæåìi sæí duûng Ngæåìi sæí duûng
Giao diãûn
Thæ viãûn
Giao diãûn låìi goüi hãû thäúng
Chæång trçnh tiãûn êch chuáøn
(Shell, Editor, compiler, ..)
Thæ viãûn chuáøn
(Open, Close, Read, Write, ..)
Hãû âiãöu haình Unix
(process management, memory management the file system, I/O, vv)
Pháön cæïng
(CPU, memory, disks, I/O, ..)
Hçnh 1.5: Hãû thäúng phán låïp cuía UNIX
Uesr Mode Kernel Mode
∙ Hệ thống này mang tính đơn thể, nên dễ cài đặt, tìm lỗi và kiểm chứng hệ thống.
∙ Trong một số trường hợp lời gọi thủ tục có thể lan truyền đến các thủ tục khác ở các lớp bên trong nên chi phí cho vấn đề truyền tham số và chuyển đổi ngữ cảnh tăng lên, dẫn đến lời gọi hệ thống trong cấu trúc này thực hiện chậm hơn so với các cấu trúc khác.
I.4.2.c. Máy ảo (Virtual Machine)
Thông thường một hệ thống máy tính bao gồm nhiều lớp: phần cứng ở lớp thấp
nhất, hạt nhân ở lớp kế trên. Hạt nhân dùng các chỉ thị (lệnh máy) của phần cứng để tạo ra một tập các lời gọi hệ thống. Các hệ điều hành hiện đại thiết kế một lớp các chương trình hệ thống nằm giữa hệ điều hành và chương trình của người sử dụng.
Các chương trình hệ thống có thể sử dụng các lời gọi hệ thống hoặc sử dụng trực tiếp các chỉ thị phần cứng để thực hiện một chức năng hoặc một thao tác nào đó, do đó các chương trình hệ thống thường xem các lời gọi hệ thống và các chỉ thị phần cứng như ở trên cùng một lớp.
Một số hệ điều hành tổ cho phép các chương trình của người sử dụng có thể gọi dễ dàng các chương trình hệ thống và xem mọi thành phần dưới chương trình hệ thống đều là phần cứng máy tính. Lớp các ứng dụng này sử dụng khái niệm máy ảo.
Mục đích của việc sử dụng máy ảo là xây dựng các hệ thống đa chương với nhiều tiến trình thực hiện đồng thời, mỗi tiến trình được cung cấp một máy ảo với đầy đủ tài nguyên, tất nhiên là tài nguyên ảo, để nó thực hiện được.
Trong cấu trúc này phần nhân của hệ thống trở thành bộ phận tổ chức giám sát máy ảo, phần này chịu trách nhiệm giao tiếp với phần cứng, chia sẻ tài nguyên hệ thống để tạo ra nhiều máy ảo, hoạt động độc lập với nhau, để cung cấp cho lớp trên.
Ở đây cần phân biệt sự khác nhau giữa máy ảo và máy tính mở rộng, máy ảo là bản sao chính xác các đặc tính phần cứng của máy tính thực sự và cho phép hệ điều hành hoạt động trên nó, sau đó hệ điều hành xây dựng máy tính mở rộng để cung cấp cho người sử dụng.
Với cấu trúc này mỗi tiến trinh hoạt động trên một máy ảo độc lập và nó có cảm giác như đang sở hữu một máy tính thực sự.
Tiãún trçnh
û
OS
a b
Giao diãûn
láûp trçnh
Tiãún trçnh
Tiãún trçnh
Tiãún trçnh
OS OS OS
Maïy aío 2
Maïy aío 1 Maïy aío 3
Pháön cæïng
Maïy aío
Pháön cæïng
Hçnh 1.6: Mä hçnh hãû thäúng (a) Khäng coï maïy aío (b) Maïy aío
Hình vẽ trên đây cho chúng ta thấy sự khác nhau trong hệ thống không có máy ảo và hệ thống có máy ảo:
Nhận xét:
∙ Việc cài đặt các phần mềm giả lập phần cứng để tạo ra máy ảo thường rất khó khăn và phức tạp.
∙ Trong hệ thống này vấn đề bảo vệ tài nguyên hệ thống và tài nguyên đã cấp phát cho các tiến trình, sẽ trở nên đơn giản hơn vì mỗi tiến trình thực hiện trên một máy tính (ảo) độc lập với nhau nên việc tranh chấp tài nguyên là không thể xảy ra.
∙ Nhờ hệ thống máy ảo mà một ứng dụng được xây dựng trên hệ điều hành có thể hoạt động được trên hệ điều hành khác. Trong môi trường hệ điều hành Windows 9x người sử dụng có thể thực hiện được các ứng dụng được thiết kế để thực hiện trên môi trường MS_DOS, sở dĩ như vậy là vì Windows đã cung cấp cho các ứng dụng này một máy ảo DOS (VMD: Virtual Machine DOS) để nó hoạt động như đang hoạt động trong hệ điều hành DOS. Tương tự trong môi trường hệ điều hành Windows NT người sử dụng có thể thực hiện được các ứng dụng được thiết kế trên tất cả các hệ điều hành khác nhau, có được điều này là nhờ trong cấu trúc của Windows NT có chứa các hệ thống con (subsystems) môi trường tương thích với các môi trương hệ điều hành khác nhau như: Win32, OS/2,..., các ứng dụng khi cần thực hiện trên Windows NT sẽ thực hiện trong các hệ thống con môi trường tương ứng, đúng với môi trường mà ứng dụng đó được tạo ra.
I.4.2.d.Mô hình Client/ Server (client/ server model)
Các hệ điều hành hiện đại thường chuyển dần các tác vụ của hệ điều hành ra các lớp bên ngoài nhằm thu nhỏ phần cốt lõi của hệ điều hành thành hạt nhân cực tiểu (kernel) sao cho chỉ phần hạt nhân này phụ thuộc vào phần cứng. Để thực hiện được điều này hệ điều hành xây dựng theo mô hình Client/ Server, theo mô hình này hệ điều hành bao gồm nhiều tiến trình đóng vai trò Server có các chức năng chuyên biệt như quản lý tiến trình, quản lý bộ nhớ, ..., phần hạt nhân cuả hệ điều hành chỉ thực hiện nhiệm vụ tạo cơ chế thông tin liên lạc giữa các tiến trình Client và Server.
Như vậy các tiến trình trong hệ thống được chia thành 2 loại:
∙ Tiến trình bên ngoài hay tiến trình của chương trình người sử dụng được gọi là các tiến trình Client.
∙ Tiến trình của hệ điều hành được gọi là tiến trình Server. Khi cần thực hiện một chức năng hệ thống các tiến trình Client sẽ gởi yêu
cầu tới tiến trình server tương ứng, tiến trình server sẽ xử lý và trả lời kết quả cho tiến trình Client.
Nhận xét:
∙ Hệ thống này dễ thay đổi và dễ mở rộng hệ điều hành. Để thay đổi các chức năng của hệ điều hành chỉ cần thay đổi ở server tương ứng, để mở rộng hệ điều hành chỉ cần thêm các server mới vào hệ thống.
∙ Các tiến trình Server của hệ điều hành hoạt động trong chế độ không đặc quyền nên không thể truy cập trực tiếp đến phần cứng, điều này giúp hệ thống được bảo vệ tốt hơn.
Tiãún trçnh Client
Tiãún trçnh Client
Server quaín lyï tiãún trçnh
Server
quaín lyï File ...
Server quaín lyï bäü nhåï
Haût nhán (kernel)
Client gửi yêu cầu đến server
Hçnh 1.7: Mä hçnh client- server
⮚ Hình vẽ sau đây cho thấy cấu trúc của hệ điều hành Windows NT. Đây là một cấu trúc phức tạp với nhiều thành phần khác nhau và nó được xây dựng dựa trên mô hình hệ điều hành Client/ Server.
Trong cấu trúc này chúng ta thấy nổi rõ hai điểm sau đây:
∙ Cấu trúc của windows NT được chia thành 2 mode: Kernel mode và User mode. Các chương trình ứng dụng của người sử dụng chỉ chạy trong User mode, các dịch vụ của hệ điều hành chỉ chạy trong Kernel mode. Nhờ vậy mà việc bảo vệ các chương trình của người sử dụng cũng như các thành phần của hệ điều hành, trên bộ nhớ, được thực hiện dễ dàng hơn.
Logon
Process
Security
SubSystem
User Mode
Kernel Mode
OS/2
Client
OS/2
SubSystem
Win32
Client
Win32
SubSystem
POSIX
Client
POSIX
SubSystem
∙ Trong User mode của Windows NT có chứa các hệ thống con môi trường như: OS/2 subsystem và POSIX subsystem, nhờ có các hệ thống con môi trường này mà các ứng dụng được thiết kế trên các hệ điều hành khác vẫn chạy được trên hệ điều hành Windows NT. Đây là điểm mạnh của các hệ điều hành Microsoft của từ Windows NT.
Chúng tôi sẽ giải thích rõ hơn về hai khái niệm Kernel mode và User mode, và các thành phần trong cấu trúc của hệ điều hành Windows NT ở phần sau, thông qua việc giới thiệu về hệ điều hành Windows 2000.
I.12. Hệ điều hành Windows95
I.5.4. Giới thiệu về hệ điều hành Windows95
Windows95 là kết quả của một sự phát triển lớn từ windows31. Microsoft không chọn giải pháp nâng cấp windows31 mà nó thực hiện việc kiến trúc lại windows để nó đủ mạnh để nó có thể thực hiện được các ứng dụng 32 bít trong một môi trường ổn định. Kết quả là Microsoft có được một phiên bản hệ điều hành windows95 đủ mạnh, có độ tin cậy và độ ổn định cao, và đặc biệt là cho phép các ứng dụng 16 bít và DOS chạy trên môi trường của nó.
Windows95 giữ lại các thành phần hệ thống của windows31 để đảm bảo tương thích với Win16, USER16, GDI và các thành phần Kernel 16 bit.
Một trong những thành phần quan trọng của windows95 là thành phần Thunking. Nhờ có Thunking mà các modun 16 bít có thể giao tiếp với các bản sao 32 bít của chúng và ngược lại. Thunking là một tập các thường trình, mà nó ánh xạ các địa chỉ để cho phép các ứng dụng phân đoạn 16 bít chia sẻ hoàn toàn bộ nhớ phẳng (flat) với các ứng dụng 32 bít. Hình vẽ sau đây cho thấy vai trò và vị trí của lớp Thunking trong windows95.
Win 16 virtual machine
Win 16 Appli cation
USER 16
(User. exe)
GDI 16
(Gdi. exe)
KERNEL 16 (krnl386.exe)
T H U N K I
N G
USER 32 (User32.dll)
GDI 32
(Gdi32.dll)
KERNEL32 (krnl32.dll)
Win 32 Appli cation
Hình 1.9: Lớp Thunking trong Windows95
⮚ Kiến trúc 32 bítcủa Intel
Hãng Intel đưa ra vi xử lý 32 bít (80386) đầu tiên cách đây 10 năm, nhưng đến khi hệ điều hành windows95 ra đời thì những điểm mạnh trong kiến trúc của nó mới được phát huy, vì windows95 đã tận dụng được các điểm mạnh trong kiến trúc của Intel 32 bítđể xây dựng thành một hệ điều hành 32 bít đủ mạnh. Các hệ điều hành 32 bít có thể truy xuất bộ nhớ theo mô hình bộ nhớ phẳng, trong mô hình này hệ điều hành có thể đánh địa chỉ bộ nhớ theo kiểu tuyến tính lên đến 4Gb, tức là nó loại trừ được sự phân đoạn bộ nhớ mà chúng ta đã thấy trong các hệ điều hành 16 bit. Khi chạy trên vi xử lý 80386 hệ điều hành windows95 khai thác tối đa các điểm mạnh trong chế độ ảo của vi xử lý này, vi xử lý 80386 có thể hoạt động ở các chế độ: thực (real mode), bảo vệ (protected mode) và ảo (virtual mode). Chế độ ảo của 80386 còn được gọi là chế độ 8086 ảo, trong chế độ 8086 ảo ngoài việc cung cấp không gian bộ nhớ ảo cho các ứng dụng, 80386 còn cho phép các ứng dụng chế độ 8086 ảo thực thi trong chế độ 8086 ảo, thực tế thực thi trong chế độ bảo vệ. Các ứng dụng chạy trong chế độ bảo vệ được hệ điều hành bảo vệ trên bộ nhớ và được truy xuất một không gian bộ nhớ lớn hơn (đến 4Gb bộ nhớ RAM). Nhờ có chế độ 8086 ảo mà windows95 có thể cho chạy nhiều ứng dụng đồng thời, kể cả các ứng dụng 16 bít của DOS và các ứng dụng 32 bítcủa windows, trên bộ nhớ và các ứng dụng này được hệ điều hành bảo vệ để các ứng dụng không truy xuất bất hợp lệ lên các vùng nhớ của nhau, nếu có một ứng dụng bị hỏng thì các ứng dụng còn lại vẫn
hoạt động bình thường. Windows95 xây dựng các máy ảo DOS để chạy các ứng dụng 16 bít của DOS.
Intel 80386 là một vi xử lý 32 bít, nhưng nếu sử dụng với hệ điều hành 16 bít thì các hệ điều hành này xem nó như là các vi xử lý 80286 16 bít, nên khả năng quản lý bộ nhớ của nó sẽ bị giới hạn. Việc xử lý dữ liệu trong môi trường 32 bít cũng có nhiều điểm lợi hơn trong môi trường 16 bít. Cùng một ứng dụng đó nhưng nếu chạy trong môi trường 16 bít thì nó phải chia thành các phân đoạn 16 bít và chỉ có thể truy xuất dữ liệu trong không gian 64Kb, nhưng khi chạy trong môi trường 32 bít thì nó không cần chia nhỏ và có thể truy xuất dữ liệu trong không gian bộ nhớ 4Gb, trong trường hợp này dữ liệu được tham chiếu theo kiểu tuyến tính nên tốc độ truy xuất được cải thiện hơn.
⮚ Kiến trúc vòng bảo vệ của Intel
Kiến trúc vòng của Intel là cơ sở để hệ điều hành windows95 xây dựng các cơ chế bảo vệ các vùng nhớ đã cấp phát cho các ứng dụng trong môi trường có nhiều ứng dụng hoạt động đồng thời, cũng như bảo vệ vùng nhớ của hệ điều hành, không cho các ứng dụng truy xuất lên vùng nhớ của nhau và không cho các ứng dụng truy xuất lên vùng nhớ chứa chính hệ điều hành.
Tất cả các vi xử lý Intel từ 80386 trở về sau đều duy trì kiến trúc 4 vòng (Ring), các ring cũng được hiểu như là các cấp độ ưu tiên của hệ thống, tuy nhiên windows95 chỉ sử dụng hai ring: ring 0 và ring 3. Trong windows95 tất cả các ứng dụng đều chạy tại ring 3 (được xem như chế độ người sử dụng), mà nó được ngăn cản truy xuất đên các vùng nhớ khác. Điều này đảm bảo rằng một ứng dụng không thể làm hỏng toàn bộ hệ thống. Các thành phần của hệ điều hành chạy tại ring 0 (được xem như chế độ kernel), các tiến trình chạy tại ring 0 không bị giới hạn truy xuất đến hệ thống (ring 0 có độ ưu tiên cao nhất, ring 3 có độ ưu tiên thấp nhất) nên code của nó phải thực sự tin cậy. Các tiến trình ở ring 3 phải thông qua các tiến trình ở ring 0 để truy xuất vào hệ thống.
⮚ Mô hình đa nhiệm trong Windows95
Windows95 là hệ điều hành đa nhiệm, nhờ có khả năng đa nhiệm mà windows95 có thể cho phép nhiều ứng dụng hoạt động đồng thời, nếu có một ứng dụng trong số này bị hỏng không thể tiếp tục thì các ứng dụng còn lại vẫn hoạt động bình thường. Windows95 có hai hình thức đa nhiệm: Đa nhiệm hợp tác (Cooperative Multitasking) và đa nhiệm ưu tiên (Preemptive Multitasking).
Trong mô hình đa nhiệm hợp tác, chỉ có ứng dụng đang sở hữu processor mới quyết định khi nào trở lại processor cho tiến trình khác hoạt động. Trong mô hình đa nhiệm ưu tiên thì việc chuyển processor từ ứng dụng hiện tại cho tiến trình khác được thực hiện bởi bộ phận lập lịch của hệ điều hành. Bộ phận lập lịch quyết định thời gian mà mỗi tiến trình được sở hữu processor, khi nào thì dừng tiến trình hiện tại để thu hồi processor, khi có được processor thì chuyển nó cho tiến trình
nào trong số các tiến trình đang chờ được cấp processor. Bộ phận lập lịch thường dựa vào độ ưu tiên của tiến trình để quyết định việc cấp processor cho nó. Các ứng dụng win32 đều hoạt động trong môi trường đa nhiệm ưu tiên, trong khi đó các ứng dụng win16 hoạt động trong môi trường đa nhiệm hợp tác.
I.5.5. Cấu trúc của windows95
Có nhiều thành phần tạo nên cấu trúc của windows95, mỗi thành phần thực hiện một chức năng nào đó của môi trường windows. Windows95 có 4 thành phần chính:
⮚ Máy ảo hệ thống (VM: virtual machine):
Một trong những thành phần chính của windows95 là trình quản lý máy ảo. Trình quản lý máy ảo điều khiển các ứng dụng MS_DOS, các ứng dụng windows, các trình điều khiển thiết bị ảo (VxD), và các thành phần cơ sở chính của windows. Các máy ảo có thể là máy ảo hệ thống hoặc các máy ảo DOS.
Máy ảo hệ thống cung cấp đầy đủ các chức năng dành riêng cho người sử dụng windows95, nhờ có nó mà các chương trình của người sử dụng có thể chạy trên windows. Nó gồm 3 yếu tố chính: Các ứng dụng windows 32bit, shell, và các ứng dụng windows 16 bít:
∙ Các ứng dụng windows 32 bít: là các ứng dụng dành riêng cho win32, nó cung cấp khả năng đa nhiệm tốt hơn so với các ứng dụng 16 bít. Tất cả các ứng dụng 32 bít dều sử dụng một không gian địa chỉ duy nhất. Windows sử dụng chế độ đa nhiệm ưu tiên (preemptive multitasking) để đảm bảo mỗi tác vụ đều được chia sẻ công bằng tài nguyên của hệ thống.
∙ Môi trường shell: đó là windows explorer, explorer cung cấp đầy đủ các khả năng 32 bít. Hay nói cách khác Shell là một ứng dụng 32 bit. ∙ Các ứng dụng windows 16 bít: đó là các ứng dụng được xây dựng trên các hệ điều hành trước windows95. Windows95 cho chạy tất cả các ứng dụng này trong một không gian địa chỉ dùng chung và các ứng dụng này được đối xử như một tác vụ duy nhất. Windows sử dụng chế độ đa nhiệm hợp tác (cooperative multitasking) cho các ứng dụng ở đây.
⮚ Máy ảo DOS (VMD: virtual machine DOS): Là thành phần dành riêng cho các ứng dụng MS_DOS. Nhờ có các máy ảo DOS mà các ứng dụng được xây dựng trên nền hệ điều hành MS_DOS vẫn có thể chạy trên môi trường hệ điều hành windows95. Có thể có nhiều máy ảo đồng thời chạy trên windows, nhờ đó mà ta có thể cho phép nhiều ứng dụng DOS chạy trên môi trường windows. Mỗi máy ảo có một vùng nhớ riêng của nó và nó đều truy xuất đến các thiết bị trên hệ thống. Các máy ảo DOS chạy trong chế độ 8086 ảo của các vi xử lý, nhờ đó mà nó được bảo vệ và nếu có một ứng dụng DOS bị hỏng khi đang chạy (Crash) thì các ứng dụng khác vẫn hoạt động bình thường.
⮚ Giao diện lập trình ứng dụng (API: application Programming Interface): Có 2 loại API 16 bít và 32 bít. API 32 bít của windows95 cung cấp một tập các dịch vụ mà tất cả các ứng dụng 32 bít có thể truy xuất được, các ứng dụng Win 32 bít được hưởng các lợi ích mà giao diện API này cung cấp. API 32 bít bao gồm các thành phần cơ bản: KERNEL32.DLL, USER32.DLL, GDI32.DLL, các thành phần này được gọi là hệ thống con windows (windows subsystem):
∙ Kernel32.DLL: Phần hạt nhân của windows, nó cung cấp một sự hỗ trợ cho những chức năng ở mức thấp mà một ứng dụng cần để chạy, nếu ứng dụng cần bộ nhớ thì nó sẽ nhận từ Kernel.
∙ GDI32.DLL: Giao diện thiết bị đồ họa của windows, nó thực hiện các chức năng về Font chữ, máy in, màn hình, ...
∙ User32.DLL: Giao tiếp người sử dụng.
⮚ Hệ thống cơ sở (Base System): Thành phần này chứa tất cả các dịch vụ đặc trưng của hệ điều hành. Đây là phần lõi (core) của widows95, nó bao gồm: ∙ Hệ thống con quản lý tập tin (File Management): thành phần này cung cấp một khả năng giao tiếp với tất cả các thiết bị khối có trên máy tính, nối trực tiếp hoặc thông qua mạng, nó giúp máy tính truy xuất được đến các thiết bị này.
∙ Hệ thống con quản mạng (Network Management Subsystem) ∙ Các dịch vụ hệ điều hành (Operating System Services)
∙ Bộ quản lý máy ảo (Virtual Machine Manager): Bộ phận này thực hiện các nhiệm vụ sau: Lập lịch cho các tác vụ; Khởi động cũng như kết thúc mọi ứng dụng có trên hệ thống, kể cả các ứng dụng DOS; Cấp phát bộ nhớ và quản lý cả bộ nhớ ảo của hệ thống; Giúp các tiến trình trao đổi thông tin với nhau.
∙ Các trình điều khiển thiết bị: Các trình điều khiển thiết bị tiếp nhận các yêu cầu của windows và trao chúng cho các thiết bị dưới khuôn dạng mà thiết bị đó có thể hiểu được. Windows95 hỗ trợ hai loại trình điều khiển thiết bị. Thứ nhất, là trình điều khiển thiết bị chế độ thực, hoạt động trong chế độ thực, mà ta đã dùng trong windows3.1. Thứ hai, là các trình điều khiển thiết bị ảo, hoạt động trong chế độ bảo vệ, đó là các VxD: Virtual Anything Drivers, các VxD cho phép windows trao đổi với các thiết bị mà không cần chuyển qua chế độ thực. Với các VxD hệ thống sẽ chạy ổn định hơn, nhanh hơn, và khả năng phục hồi lỗi tốt hơn so với các trình điều khiển thiết bị trong chế độ thực. Tuy nhiên các VxD có thể làm hỏng hệ thống, vì code của nó hoạt động tại ring 0.
⮚ Một thành phần không thể không nhắc đến trong môi trường windows đó là các DLL (Dynamic Link Liblary: Thư viện liên kết động): Trong môi
trường hệ điều hành Windows, tại một thời điểm có thể có nhiều chương trình đồng thời hoạt động, và các chương trình này có thể cùng sử dụng một đoạn mã giống nhau nào đó. Như vậy trong bộ nhớ sẽ tồn tại nhiều đoạn mã giống nhau để đáp ứng cho các chương trình khác nhau, điều này gây lãng phí bộ nhớ. Để khắc phục Windows 9x đưa ra các tập tin DLL, DLL chứa các đoạn mã mà các ứng dụng thường sử dụng. DLL được nạp vào bộ nhớ ngay sau khi khởi động hệ điều hành để sẵn sàng phục vụ các ứng dụng hoặc được nạp vào bộ nhớ khi nó được gọi lần đầu tiên. Hệ điều hành luôn giám sát việc sử dụng DLL của các ứng dụng, khi không còn một ứng dụng nào sử dụng DLL thì nó được giải phóng ra khỏi bộ nhớ. Các mã trong DLL sẽ được liên kết vào các ứng dụng khi các ứng dụng được nạp vào bộ nhớ, các ứng dụng truy cập vào hệ thống thông qua các DLL. Như vậy nhờ có DLL mà windows linh động hơn và tiết kiệm được nhiều bộ nhớ hơn.
I.5.6. Bộ nhớ ảo (Virtual Memory) trong windows95
Mặc dù các tiến trình win32 có thể sử dụng đến 4GB bộ nhớ RAM, nhưng các giới hạn phần cứng hiện nay ngăn cản hầu hết các máy tính chứa nhiều bộ nhớ. Để mở rộng giới hạn bộ nhớ này các vi xử lý đã đưa ra các mô hình quản lý bộ nhớ khác nhau nhằm mở rộng khả năng quản lý bộ nhớ của vi xử lý cũng như cung cấp nhiều hơn không gian bộ nhớ cho các tiến trình. Vi xử lý 80386 đã sử dụng mô hình bộ nhớ ảo.
Với vi xử lý 80386 không gian bộ nhớ được chia thành các phân đoạn (segmentation), mỗi phân đoạn lại được chia thành các phân trang (paging), các phân trang đều có kích thước bằng nhau và bằng 4Kb. CPU cũng như hệ điều hành sử dụng các trang bộ nhớ để chứa code và data của các tiến trình, trong trường hợp này các tiến trình cũng được chia thành các trang có kích thước bằng các trang bộ nhớ.
Trong mô hình bộ nhớ ảo CPU không nạp tất cả các trang của tiến trình vào bộ nhớ RAM mà chỉ nạp các trang cần thiết ban đầu, các trang còn lại sẻ được nạp sau đó nếu cần. CPU dùng các bảng trang (PCT: Page Control Table) để theo dõi một trang của tiến trình là đã được nạp vào bộ nhớ RAM hay chưa. Khi có một trang mới của tiến trình được nạp vào bộ nhớ hoặc khi có một trang của tiến trình bị đưa ra lại đĩa thì hệ thống phải thực hiện việc cập nhật lại PCT.
Khi có yêu cầu nạp một trang tiến trình mới vào bộ nhớ nhưng trên bộ nhớ không còn trang trống thì CPU cùng với hệ điều hành sẽ tìm một trang tiến trình nào đó không thực sự cần thiết tại thời điểm hiện tại, thường là trang ít được sử dụng gần đây nhất, để đưa ra đĩa (swap out), để lấy khung trang trống đó nạp trang tiến trình vừa yêu cầu, trang tiến trình bị đưa ra đĩa này sẽ được CPU và hệ điều hành nạp vào lại bộ nhớ (swap in) tại một thời điểm thích hợp sau này. Các trang bị swap out thường được chứa trong một tập tin nào đó trên đĩa cứng, và được gọi là các tập tin swap. Trong windows95 các tập tin swap không bị giới hạn kích thước.
Khi người sử dụng khởi động một ứng dụng thì windows95 sẽ khởi tạo một tập tin swap có kích thước ban đầu bằng kích thước của ứng dụng để sẵn sàng chứa các trang của ứng dụng khi các trang này bị CPU swap out ra đĩa.
Windows95 thiết kế các tập tin swap theo kiểu động, tức là kích thước của nó có thể thay đổi tuỳ theo số trang mà nó chứa. Nếu có nhiều trang bị swap out thì kích thước của nó tăng lên, nếu các trang trong nó được swap in vào lại bộ nhớ RAM thì kích thước của nó sẽ tự động giảm xuống.
I.13. Hệ điều hành Windows 2000
I.6.5. Giới thiệu về hệ điều hành Windows 2000
Windows 2000 được thiết kế để chạy trên các kiến trúc phần cứng khác nhau như: Các hệ thống dựa trên nền Intel CISC và RISC, Alpha AXP, Motorola PowerPC, .... Nó được viết bởi C và C++, ngôn ngữ assembly chỉ được sử dụng để viết các thành phần giao tiếp trực tiếp với phần cứng, mã ngôn ngữ assembly không chỉ tồn tại trong kernel và HAL mà nó còn tồn tại trong phần kernel mode của hệ thống con Win32, và trong một vài thư viện của user mode.
Windows 2000 là hệ điều hành đa xử lý (multiprocess) 32 bít, được xây dựng để quản lý các hệ thống mạng máy tính, nó hỗ trợ cả 2 mô hình mạng: client/server (server-based) và peer-to-peer.
Windows 2000 được xây dựng dựa trên Windows NT 4.0, nó cung cấp nhiều công cụ tốt hơn để quản lý Internet và các dịch vụ trên Internet. Windows 2000 là một họ gồm có 4 sản phẩm, một cho client và ba cho server: Client: Windows 2000 Professional; Server: Windows 2000 Server, Windows 2000 Advanced Server, Windows 2000 datacenter Server
Các sản phẩm trên khác nhau ở các điểm sau:
∙ Số các processor được hỗ trợ.
∙ Số lượng bộ nhớ vật lý được hỗ trợ.
∙ Số các kết nối mạng hiện tại được hỗ trợ.
∙ Các dịch vụ có trong các sản phẩm server không có trong sản phẩm client.
Các file chính của Windows 2000 bao gồm:
∙ Ntoskrnl.exe: Thành phần Executive và Kernel của hệ điều hành. ∙ Ntkrnlpa.exe: Thành phần Executive và Kernel với sự hỗ trợ để mở rộng bộ nhớ vật lý, nó cho phép địa chỉ hoá bộ nhớ vật lý lên đến 64GB.
∙ Hal.dll: Lớp phần cứng trừu tượng.
∙ Win32k.sys: Bộ phận kernel mode của hệ thống con Win32. ∙ Ntdll.dll: Hỗ trợ sự điều phối để thực hiện các hàm.
∙ Kernel32.dll, Advapi32.dll, User32.dll, Gdi32.dll: Các file chính của hệ thống con Win32 DLLs.
I.6.6. Một số đặc tính của Windows 2000
⮚ Windows 2000 so với các Windows khác:
∙ Windows 2000 hỗ trợ các hệ thống multiprocessor các windows khác không hỗ trợ điều này.
∙ Windows 2000 hỗ trợ hệ thống file an toàn các windows khác không có hệ thống file an toàn.
∙ Windows 2000 là hệ điều hành 32 bít đầy đủ, nó không chứa các mã 16 bít, nó hỗ trợ các mã khác để chạy các ứng dụng windows 16 bít. Các windows khác chứa một lượng lớn các mã 16 bít cũ từ các phiên bản trước. Đây là điểm khác biệt lớn của windows 2000 so với windows 3.1 và MS_DOS.
∙ Windows 2000 cung cấp một tùy chọn để chạy các ứng dụng windows 16 bít, mà mỗi ứng dụng sở hữu một không gian địa chỉ riêng. Trong các hệ điều hành windows khác các ứng dụng windows 16 bít luôn chạy trong không gian địa chỉ bộ nhớ được chia sẻ, mà ở đó các ứng dụng có thể bị làm hỏng bởi các ứng dụng khác.
∙ Bộ nhớ được chia sẻ trong Windows 2000 là chỉ nhìn thấy khi các tiến trình ánh xạ đến cùng một vùng nhớ được chia sẻ, trong Win32 API một vùng bộ nhớ được chia sẻ được gọi là file ánh xạ. Trong các hệ điều hành windows khác tất cả bộ nhớ được chia sẻ là được nhìn thấy và được ghi bởi tất cả các tiến trình. Do đó bất kỳ một tiến trình nào cũng có thể ghi đến bất kỳ file ánh xạ.
∙ Trong các hệ điều hành windows khác một vài trang (page) quan trọng của hệ điều hành trên bộ nhớ là có thể được ghi từ user mode, vì thế một ứng dụng của người sử dụng có thể là hỏng hệ thống (ghi đè lên hệ điều hành). Điều này không xảy ra đối với hệ điều hành Windows 2000.
⮚ Đặc tính của Windows 2000 Server:
∙ Windows 2000 server cung cấp chế độ Safe mode, cho phép khởi tạo windows 2000 server với tập các thiết bị và dịch vụ tối thiểu nhất. Nó cũng hỗ trợ chức năng Plug-n-Play.
∙ Windows 2000 server hỗ trợ các ứng dụng trên nền MS_DOS, các ứng dụng 16/32 bít trên nền Windows, ... và nó cũng đưa ra các cơ chế để bảo vệ các ứng dụng khi các ứng dụng này hoạt động trên bộ nhớ.
∙ Windows 2000 server cung cấp tiện ích Backup, chức năng Automated System Recorver, để backup dữ liệu, khôi phục dữ liệu khi dữ liệu tình cờ bị mất, recover và restore hệ thống trong trường hợp lỗi nghiệm trọng xảy ra trên đĩa cứng.
∙ Windows 2000 server cung cấp các công cụ cấp cao cho các hệ thống cần có độ ổn định và khả năng chịu đựng lỗi cao.
∙ Windows 2000 server cho phép quản lý 2 hệ thống đĩa: Basic disk và Dynamic Disk. Nó cũng hỗ trợ các hệ thống tập tin: FAT, NTFS, CDFS. ∙ Windows 2000 server hỗ trợ các hệ thống Symmetric Multiprocessing, có từ 4 đến 8 processor. Nó cũng có thể quản lý được từ 4GB đến 8GB bộ nhớ vật lý.
∙ Windows 2000 advanced server hỗ trợ các hệ thống Clusters. Cluster là một nhóm các server được kết nối để cùng làm việc với nhau, nếu một server trong cluster bị hỏng thì một server khác trong cùng cluster sẽ được thay thế để hoàn thành tác vụ mà server đó (server bị hỏng) đang thực hiện.
∙ Windows 2000 Datacenter Server hỗ trợ 32-way SMP nhờ OEM (original equipment manufacturer) và có khả năng quản lý đến 64 GB bộ nhớ vật lý. Đặc tính này giúp các server Windows 2000 trở thành các trung tâm dữ liệu (database centric), các kho dữ liệu lớn (data warehouses) phục vụ cho các Internet Service Provider và host Web site.
I.6.7. Một số khái niện trong Windows 2000
I.5.3.a.Tiến trình (Process) và tiểu trình (Thread)
⮚ Tiến trình: Người sử dụng khó có thể phân biệt sự khác nhau giữa chương trình và tiến trình, mặc dù nó có các sự khác nhau rất cơ bản. Một chương trình là một dãy tĩnh các chỉ thị, trong khi đó tiến trình là nơi chứa một tập các tài nguyên được sử dụng bởi các tiểu trình mà các tiểu trình này thực hiện một đoạn mã đặc biệt nào đó của chương trình. Các tiến trình của Windows 2000 bao gồm:
∙ Một không gian địa chỉ ảo riêng, đó là một tập các địa chỉ bộ nhớ ảo mà các tiến trình có thể sử dụng.
∙ Một chương trình có thể thực hiện được, mà nó định rõ bất kỳ một code và data ban đầu nào và nó được ánh xạ vào không gian địa chỉ của tiến trình.
∙ Một danh sách mở các tài nguyên hệ thống khác nhau mà tiến trình sử dụng như các semaphore (sự đánh tín hiệu bằng cờ), các cổng giao tiếp tiến trình, các file, … , các tài nguyên này được truy cập bởi tất cả các tiểu trình trong tiến trình.
∙ Một ngữ cảnh an toàn (security context), được gọi là thẻ truy cập
(access token), nó định danh người sử dụng, các nhóm an toàn, và các cấp đặc quyền có liên quan với tiến trình.
∙ Một định danh duy nhất, được gọi là Process ID.
∙ Có ít nhất một tiểu trình.
⮚ Tiểu trình: Một tiểu trình là một thực thể trong tiến trình mà hệ điều hành có thể lập lịch để nó thực hiện, không có nó thì các tiến trình của nó không thể thực hiện được. Một tiểu trình bao gồm các thành phần cơ bản sau:
Access token
Process
Object
Handle
Table
Virtual Address Descriptors
VAD VAD VAD
Object
Object
Thread Thread Thread ... Access token
Hình 1.10: Các tiến trình và tài nguyên của nó
∙ Nội dung của các thanh ghi trong CPU miêu tả trạng thái của processor.
∙ Hai Stack, một cho tiểu trình sử dụng khi thực hiện trong kernel mode và một cho tiểu trình sử dụng trong user mode.
∙ Một vùng lưu trữ riêng được gọi là TLS (theard local storage) để sử dụng bởi các hệ thống Connection, các thư viện run-time, và các DLL.
∙ Một định danh duy nhất, được gọi là Theard ID.
∙ Đôi khi các tiểu trình cũng sở hữu một ngữ cảnh an toàn riêng, nó thường được sử dụng bởi các ứng dụng server đa tiểu trình. Các thanh ghi, các stack và các vùng lưu trữ riêng được gọi là
ngữ cảnh của tiểu trình. Bởi vì các thông tin này là khác nhau cho mỗi kiến trúc máy khác nhau mà Windows 2000 chạy trên nó. Cấu trúc
ngữ cảnh này được trả về bởi hàm Win32 API GetThreardContexxt. Mặc dù các tiểu trình có một ngữ cảnh thực hiện riêng, nhưng mỗi tiểu trình trong phạm vi một tiến trình đều chia sẻ không gian địa chỉ ảo của tiến trình, điều này có nghĩa rằng tất cả các tiểu trình trong một tiến trình có thể ghi đến hoặc đọc từ bộ nhớ của tiểu trình khác. Các tiểu trình không thể tham chiếu đến không gian địa chỉ của các tiến trình khác, trừ khi tiến trình khác đó đưa ra một phần không gian địa chỉ riêng của nó như là một phần bộ nhớ được chia sẻ.
Ngoài không gian địa chỉ riêng và một hoặc nhiều tiểu trình, mỗi tiến trình còn có một định danh an toàn và một danh sách điều khiển các đối tượng như là các file, các section bộ nhớ được chia sẻ hoặc một hoặc nhiều đối tượng đồng bộ như là: các mutexe, các event, các semaphore (sự đánh tín hiệu bằng cờ). Điều này được minh họa ở hình trên.
I.5.3.b. Bộ nhớ ảo (Virtual Memory) trong windows 2000
Windows 2000 cài đặt một hệ thống bộ nhớ ảo dựa trên một không gian địa chỉ 32 bít. Ba hai bít của địa chỉ ảo này chuyển thành 4GB bộ nhớ ảo. Windows 2000 dùng nửa thấp của 4GB này cấp cho các tiến trình, nửa còn lại dành riêng cho hệ điều hành, phần này được bảo vệ bởi chính hệ điều hành. Sự ánh xạ của nửa thấp thay đổi để tương ứng với tiến trình đang thực hiện, nhưng sự thay đổi của nửa cao luôn phù hợp với bộ nhớ ảo của hệ điều hành.
Nhớ lại rằng, không gian địa chỉ ảo của tiến trình là một tập các địa chỉ có sẵn cho các tiểu trình của tiến trình sử dụng. Bộ nhớ ảo cung cấp một cái nhìn logic của bộ nhớ, nhờ đó nó mở rộng được sức mạnh lưu trữ tiểu trình của bộ nhớ vật lý. Trong quá trình hoạt động của hệ thống, với sự giúp đỡ của phần cứng, trình biên dịch hoặc các ánh xạ, của trình quản lý bộ nhớ sẽ chuyển địa chỉ ảo thành địa chỉ vật lý, nơi dữ liệu được lưu trữ thực tế. Bằng cách điều khiển sự bảo vệ và sự ánh xạ, hệ điều hành có thể đảm bảo rằng một tiến trình riêng lẻ không làm hỏng các tiểu trình và không ghi đè lên dữ liệu của hệ điều hành.
Hình vẽ 1.11 sau đây cho thấy có 3 trang ảo liền kề được ánh xạ thành 3 trang không liền kề trong bộ nhớ vật lý.
Bộ nhớ ảo
Bộ nhớ V.lý
Hình 1.11: Bộ nhớ ảo và bộ nhớ Vật lý
Đa số các hệ thống đều có bộ nhớ vật lý nhỏ hơn tổng số bộ nhớ ảo mà các tiến trình cần sử dụng khi thực hiên, 2 GB hoặc 3 GB cho mỗi tiến trình. Khi điều này xảy ra thì trình quản lý bộ nhớ sẽ di chuyển một nội dung của một vài trang bộ nhớ ra đĩa, để lấy không gian trang trống này sử dụng cho các tiến trình khác hoặc cho chính hệ điều hành. Khi một tiểu trình truy cập đến một trang địa chỉ ảo mà nội dung của trang này đã bị đưa ra đĩa thì bộ phận quản lý bộ nhớ ảo sẽ nạp thông tin này trở lại bộ nhớ từ đĩa. Các ứng dụng không cần thay đổi bất kỳ một điều gì để phù hợp với sự phân trang, bởi vì phần cứng đã hỗ trợ để cho phép trình quản lý bộ nhớ thực hiện sự phân trang mà không cần hiểu biết hoặc sự trợ giúp của các tiến trình hoặc các tiểu trình.
I.5.3.c. Đa xử lý đối xứng (SMP: Symmetric Multiprocessing) Đa tác vụ (multitasking) là một kỹ thuật của hệ điều hành dùng để chia sẻ một processor đơn cho nhiều tiểu trình đang thực hiện. Khi máy tính có nhiều hơn một processor thì nó có thể thực hiện hai tiểu trình đồng thời. Nhưng ngược lại hệ điều hành đa tác vụ chỉ có vẻ như thực hiện đa tiểu trình tại cùng một thời điểm, hệ điều hành đa xử lý thực tế làm được điều đó, thực hiện một tiểu trình trên mỗi processor của nó.
Một trong những mục tiêu thiết kế của hệ điều hành Windows NT là làm cho NT chạy tốt trên các hệ thống máy tính multiprocessor. Windows 2000 cũng là hệ điều hành SMP. Nó không có processor master, hệ điều hành cũng như các tiểu trình của người sử dụng đều có thể được chia sẻ trên bất kỳ một processor nào. Ngoài ra, tất cả các processor cũng chỉ chia sẻ một không gian bộ nhớ riêng. Đây là mô hình tương phản với mô hình đa xử lý bất đối xứng (ASMP: asymmetric multiprocisor), trong mô hình này hệ điều hành chạy trên một processor riêng, các processor còn lại chỉ dùng để chạy các tiểu trình của người sử dụng.
Số processor sử dụng phụ thuộc vào phiên bản Windows 2000 được sử dụng. Con số này được lưu trữ trong Registry tại khoá:
HKLM\SYSTEM\CurrentControlSet\Control\Session\Manager\LicensedPro cessor
Để chạy tốt trên một hệ thống SMP thì hệ điều hành Windows 2000 phải được thiết kế sao cho nó phải tuân thủ một cách nghiêm ngặt các nguyên tắc sau đây, đó là các nguyên tắc của một hệ điều hành Multiprocessor:
∙ Có khả năng chạy mã của hệ điều hành trên bất kỳ một processor có sẵn nào và chạy được trên multiprocessor tại cùng một thời điểm.
∙ Đa tiểu trình được thực hiện trong một tiến trình đơn, mỗi tiểu trình có thể thực hiện đồng thời trên các processor khác nhau.
∙ Cho phép các thành phần khác nhau của hệ thống như device driver, server process chạy tốt trên hệ thống multiprocessor.
I.6.8. Kiến trúc của Windows 2000
⮚ Kernel Mode & User Mode
Để bảo vệ hệ điều hành tránh sự truy cập và/hoặc thay đổi bất hợp lệ của các chương trình ứng dụng của người sử dụng, Windows 2000 sử dụng hai chế độ xử lý truy cập: Kernel mode và User mode. Các chương trình ứng dụng của người sử dụng chạy trong user mode, trong khi đó các dịch vụ hệ thống và các chương trình điều khiển thiết bị của hệ điều hành chạy trong kernel mode. Kernel mode chỉ đến một chế độ của việc thực hiện trong processor mà ở đó nó có toàn quyền truy cập đến tất cả hệ thống bộ nhớ và tất cả các chỉ thị của CPU. Trong cấu trúc này phần mềm hệ điều hành được cung cấp một mức đặc quyền cao hơn so với mức đặc quyền của các chương trình ứng dụng của người sử dụng. Processor cung cấp các cơ sở cần thiết để người thiết kế hệ điều hành đảm bảo rằng các ứng dụng không thể phá vỡ trạng thái ổn định của hệ thống và làm hỏng nó.
Các tiểu trình trong user mode thực hiện trong không gian địa chỉ bộ nhớ được bảo vệ, mỗi thành phần trong user mode sở hữu một không gian địa chỉ tiến trình riêng. Trong khi đó Windows 2000 không cung cấp bất kỳ một sự bảo vệ nào trên các không gian bộ nhớ riêng được sử dụng bởi các thành phần chạy trong kernel mode. Trong một tuyên bố khác, trong kernel mode, mã hệ điều hành và các chương trình điều khiển thiết bị hoàn toàn có thể truy cập đến không gian bộ nhớ hệ thống và có thể vượt qua sự giám sát an toàn của Windows 2000 để truy cập đến các đối tượng. Bởi vì phần lớn mã của hệ điều hành Windows 2000 chạy trong kernel mode, các thành phần quan trọng nhất của hệ điều hành chạy trong kernel mode được thiết kế và được kiểm tra rất cẩn thận để đảm bảo rằng nó không vi phạm đến sự an toàn của hệ thống.
Chú ý: Kiến trúc của processor Intel x86 định nghĩa 4 cấp/ vòng đặc quyền truy cập (Privilege levels/ Rings), để bảo vệ code và data của hệ thống, tránh sự ghi đè (overwrite) có chủ ý (maliciously) hoặc không chủ ý (inadvertently) bởi các code có cấp đặc quyền truy cập thấp hơn. Windows 2000 sử dụng cấp 0/ vòng 0 cho Kernl mode và cấp 3/ vòng 3 cho Uer mode. Nguyên nhân mà Windows 2000 chỉ sử dụng có 2 cấp là do một vài kiến trúc phần cứng trước đó, chẳng hạn như
Compaq Alpha và Silicon Graphics, chỉ được cài đặc 2 cấp đặc quyền truy cập. ⮚ Kiến trúc của Windows 2000
Hình vẽ 1.12 sau đây cho ta thấy kiến trúc đã được đơn giản hoá của Windows 2000.
System
Support Processes
Service Processes
User
Applicatioes
Environment SubsystemÐ
Executive
Subsystem DLLs
Windows
And Graphics
User modeKernel mode
Kernel Device Drivers
Hard Abstraction Layer
Hình 1.12: Kiến trúc được đơn giản của Windows 2000
Hình vẽ cho ta thấy kiến trúc của hệ điều hành Windows 2000 được chia thành hai phần: User mode và Kernel mode. User mode bao gồm các thành phần: System support processes, Service Processes, User applications, và Environment subsystems, mỗi thành phần này sở hữu một không gian địa chỉ tiến trình riêng.
❑ Các thành phần trong User mode:
∙ System support processes (các tiến trình hỗ trợ hệ thống): Như là tiến trình logon, quản lý các Session, các thành phần này không phải là các dịch vụ của Windows 2000, do đó nó không được khởi động bởi thành phần Service Control Manager.
Service processes (các tiến trình dịch vụ): Đó là các dịch vụ chủ Win32, như là dịch Task Scheduler và Spooler, và cungc có thể là các ứng dụng server Windows 2000 như là Microsoft SQL Server, Exchange Server và các thành phần chạy như là các dịch vụ.
∙ User applications (các ứng dụng người sử dụng): Nó có thể là một trong năm loại sau: Win32, Windows 3.1, MS_DOS, POSIX, hoặc OS/2 1.2. ∙ Environment subsystems (các hệ thống con môi trường): nó đưa ra các dịch vụ nguyên thuỷ của hệ điều hành, các ứng dụng của người sử dụng thông qua một tập các hàm có thể gọi được, do đó nó cung cấp một môi trường hệ điều hành cho các ứng dụng. Windows 2000 đưa ra ba hệ thống con môi trường: Win32, POSIX và OS/2, trong đó Win32 là hệ thống con đặc biệt nhất, Windows 2000 không thể chạy nếu không có nó, do đó nó phải
luôn ở trạng thái chạy ngay sau khi hệ thống được khởi động. POSIX và OS/2 được cấu hình là chỉ khởi tạo khi cần. Các ứng dụng được viết trên các hệ điều hành khác nhau có thể chạy trên Windows 2000 nhờ sử dụng các environment subsystem.
∙ Subsystem DLLs (hệ thống con các thư viện liên kết động): Hình trên cho thấy trong Windows 2000 các ứng dụng của người sử dụng không thể gọi trực tiếp các dịch vụ nguyên thủy của hệ điều hành, mà chúng phải thông qua một hoặc nhiều các DLL. Vai trò của các Subsystem DLL là chuyển các yêu cầu gọi hàm vào bên trong các dịch vụ hệ thống của Windows 2000.
❑ Các thành phần trong Kernel mode:
∙ Windows 2000 Executive: Chứa các dịch vụ cơ sở của hệ điều hành, như là: quản lý bộ nhớ, quản lý các tiến trình và tiểu trình, quản lý sự an toàn hệ thống, quản lý I/O, và thực hiện việc truyền thông liên tiến trình. ∙ Windows 2000 Kernel: Bao gồm các chức năng cấp thấp của hệ điều hành như là: lập lịch tiểu trình, đồng bộ cho các hệ thống multiprocessor. Nó cũng cung cấp một tập các thường trình và các đối tượng cơ sở mà Executive sử dụng để cài đặt các chức năng cấp cao.
∙ Device drivers (các trình điều khiển thiết bị): Bao gồm cả hai: điều khiển thiết bị phần cứng và điều khiển hệ thống file và mạng. Điều khiển thiết bị phần cứng có nhiệm vụ chuyển các lời gọi hàm I/O từ phía người sử dụng thành các yêu cầu I/O thiết bị phần cứng cụ thể.
∙ HAL: Hardware Abstraction Layer (lớp phần cứng trừu tượng): Lớp này làm trừu tượng hoá các chi tiết phần cứng bên trong của PC, làm cho Windows 2000 Server tương thích với nhiều kiến trúc phần cứng khác nhau. Nó cho phép Windows 2000 chạy trên các nền vi xử lý khác nhau như Intel và Alpha, mà không cần duy trì 2 version khác của Windows 2000 Execute. HAL bảo vệ tất cả phần cứng và hỗ trợ các nền cụ thể cần cho mỗi thành phần trong hệ thống đối với tất cả phần cứng và hỗ trợ nềm cụ thể. HAL được cài đặt như là một DLL và đóng vai trò như là giao diện giữa các thành phần phần cứng và phần mềm.
∙ Window Manager and Graphical Device Interface (GDI): Window Manager và GDI được sử dụng để quản lý hệ thống hiển thị. Window Manager bảo vệ màn hình và nhận các lệnh từ các thiết bị nhập như là Mouse hoặc bàn phím. GDI điều khiển việc vẽ và thực hiện các thao tác đồ hoạ với sự giúp đỡ của các chức năng khác nhau được định nghĩa trước.
Sau đây chúng ta sẽ tìm hiểu rõ hơn về một số thành phần trong kiến trúc của hệ điều hành Windows 2000:
❑ Environment Subsystem và Subsystem DLL:
Vai trò của hệ thống con môi trường là đưa ra một vài tập con cơ sở các dịch vụ hệ thống trong Windows 2000 executive cho các ứng dụng. Mỗi hệ thống con có thể cung cấp truy cập đến các tập con khác nhau của các dịch vụ nguyên thủy của Windows 2000. Từ một ứng dụng được xây dựng trên một hệ thống con này không thể gọi đến một ứng dụng được xây dựng trên một hệ thống con khác.
Các lời gọi hàm không thể lẫn lộn giữa các hệ thống con. Tức là một ứng dụng trên POSIX chỉ có thể gọi các dịch vụ được đưa ra bởi hệ thống con POSIX, và một ứng dụng Win32 chỉ có thể gọi các dịch vụ được đưa ra bởi hệ thống con Win32.
Như đã biết các ứng dụng người sử dụng không thể gọi trực tiếp các dịch vụ hệ thống của Windows 2000 mà phải thông qua một hoặc nhiều các hệ thống con DLL. Các hệ thống con DLL Win32 như kernel32.dll, Advapi32.dll, User32.dll và Gdi32.dll, cài đặt các hàm Win32 API, để các ứng dụng của người sử dụng gọi nó thông qua tập hàm này. Khi một ứng dụng gọi một hàm trong hệ thống con DLL, thì một trong ba trường hợp sau sẽ xảy ra:
∙ Hàm được cài đặt hoàn toàn trong hệ thống con DLL. Nói cách khác là không có thông điệp gởi tới tiến trình Vai trò của hệ thống con môi trường, và không có một dịch vụ hệ thống nào trong Windows 2000 executive nào được gọi. Hàm được thực hiện trong user mode và kết quả được trả về cho chương trình gọi.
∙ Hàm yêu cầu một hoặc nhiều lời gọi đến Windows 2000 executive. Ví dụ khi các hàm Win32 ReadFile và WriteFile được gọi thì nó phải gọi đến các dịch vụ hệ thống I/O NtReadFile và NtWriteFile trong Windows 2000. ∙ Hàm yêu cầu một vài công việc để thực hiện trong tiến trình,.của hệ thống con môi trường. Các tiến trình của hệ thống con môi trường chạy trong user mode, chịu trách nhiệm duy trì trạng thái của các ứng dụng client chạy dưới sự điều khiển của nó. Trong trường hợp này một client/server yêu cầu tạo một hệ thống con môi trường qua một thông điệp gởi tới một hệ thống con để thực hiện một vài thao tác. Hệ thống con DLL thì đợi trả lời trước khi trả về cho ứng dụng gọi.
Một vài hàm có thể kết hợp 2 trong 3 trường trên, như các hàm Win32: CreateProcess và CreateThread.
Tập tin Ntdll.Dll là một hệ thống đặc biệt, nó hỗ trợ thư viện chính cho việc sử dụng các hệ thống con DLL. Nó chứa hai loại hàm sau:
∙ Dịch vụ hệ thống gởi đến các dịch vụ hệ thống Windows 2000 executive.
∙ Các hàm hỗ trợ bên trong được sử dụng bởi các hệ thống con, các hệ
thống con DLL và các hàm nguyên thủy điển hình khác.
Các hàm ở nhóm đầu tiên cung cấp một giao diện để Windows 2000 executive có thể được gọi từ user mode. Có hơn 200 hàm như thế và các hàm này có thể truy cập thông qua Win32 API.
Ntdll cũng chứa các hàm hỗ trợ như là image loader, heap manager và các hàm truyền thông tiến trình Win32.
❑ Executive:
Windows 2000 executive là lớp trên của Ntoskrnl.exe (kernel là lớp thấp). Executive bao gồm các hàm sau:
∙ Các hàm được đưa ra và có thể gọi từ user mode. Đây là các hàm được gọi và được đưa ra qua Ntdll. Hầu hết các dịch vụ là được truy cập thông qua các hàm Win32 API hoặc các API của các Vai trò của hệ thống con môi trường khác.
∙ Các hàm chỉ có thể được gọi từ kernel mode, nó được đưa ra và được cung cấp in Windows 2000 DDK Windows 2000 Installable File System (IFS) Kit.
∙ Các hàm được đưa ra và có thể gọi từ kernel mode nhưng không được giới thiệu trong Windows 2000 DDK và IFS Kit.
∙ Các hàm được định nghĩa nhưng không được đưa ra. Đây là các hàm hỗ trợ bên trong, nó được gọi trong phạm vi Ntoskrnl.
Windows 2000 Executive chứa các thành phần quan trọng sau đây: ∙ Configuration Manager (quản lý cấu hình): chịu trách nhiệm cài đặt và quản lý Registry hệ thống.
∙ I/O Manager (quản lý I/O): Thành phần này chuyển các lệnh đọc/ ghi trong user mode đến việc đọc/ghi của IRP (I/O Request Packets). Nó gồm có: các hệ thống file, các điều khiển thiết bị, quản lý bộ nhớ cache, quản lý bộ nhớ ảo.
∙ InterProcess Communication - IPC Manager (quản lý truyền thông liên tiến trình): Quản lý IPC là tạo liên kết giữa client và server. Environment subsystem đóng vai trò như là một client và Executive đóng vai trò như là một server. Nó được tạo ra từ 2 thành phần: Remote Procedure Call - RPC: giữ thông tin về kết nối giữa các client và các server trên các máy tính khác nhau. Local Procedure Call - RPC: giữ thông tin về kết nối giữa các client và các server trên cùng một máy tính.
∙ Security Manager (quản lý sự an toàn): Đây là thành phần tạo nên sự an toàn hệ thống bằng cách bắt buộc các chính sách an toàn trên các máy tính cục bộ.
∙ Plug and Play Manager (quản lý plug and play): Plug and play theo dõi các hoạt động tại thời điểm Boot của các thiết bị plug and play và nó tương tác với HAL, các điều khiển thiết bị và Executive. Nó xác định các điều khiển bus thực hiện việc cấu hình và đếm như thế nào. Nó cũng xác định khi nào thì các điều khiển thiết bị được thêm vào hoặc khi nào thì khởi tạo một thiết bị.
∙ Process and Thread Manager (quản lý tiến trình và tiểu trình): Tạo và kết thúc các tiến trình và tiểu trình. Hỗ trợ các tiến trình và tiểu trình được cài đặt bên trong Windows 2000 kernel.
∙ Và một số thành phần khác như: Power manager (quản lý nguồn); Cache manager (quản lý cache); Virtual memory manager (quản lý bộ nhớ ảo), …
∙ Ngoài ra executive còn chứa bốn nhóm chính các hàm hỗ trợ mà nó được sử dụng bởi chỉ các thành phần executive được liệt kê. Sau đây là bốn loại hàm hỗ trợ:
∙ Object Manager (quản lý đối tượng): Tạo, quản lý, xoá các đối tượng Windows 2000 executive và các loại dữ liệu trừu tượng mà nó được sử dụng để chỉ đến các tài nguyên của Windows 2000 như: các tiến trình, các tiểu trình, và các đối tượng đồng bộ khác.
∙ LPC facility: Chuyển thông điệp giữa các tiến trình client và các tiến trình server trên cùng máy tính. LPC có tính mềm dẻo, và là version được tối ưu của Remote Function Call (RPC).
∙ Một tập các hàm thư viện run-time như là: xử lý string, thực hiện các phép tính, chuyển đổi các kiểu dữ liệu và xử lý các cấu trúc an toàn.
∙ Executive support routine: như là cấp phất bộ nhớ hệ thống, khoá truy cập bộ nhớ và các đối tượng đồng bộ.
❑ Kernel:
Kernel bao gồm một tập các hàm trong Ntoskrnl.exe mà nó cung cấp các kỹ thuật cơ bản, như điều phối tiểu trình và đồng bộ các dịch vụ, được sử dụng bởi các thành phần executive, cũng như hỗ trợ cho các kiến trúc phần cứng cấp thấp trên các kiến trúc processor khác nhau. Đa số các mã của kernel được viết bằng C, một số ít thành phần quan trong can thiệp sâu vào phần cứng được viết bằng assembly. Một số các hàm của kernel được đưa ra trong DDK, đây là các thành phần cần thiết cho việc cài đặt các trình điều khiển thiết bị.
❑ Hardware Abstraction Layer (HAL):
Như đã biết một trong những mục tiêu thiết kế của Windows 2000 là làm cho nó dễ
dàng tương thích trên các nền phần cứng khác nhau. HAL là thành phần chủ chốt có thể tạo nên sự tương thích này. HAL là một modun kernel mode có thể được nạp (Hal.dll) mà nó có thể cung cấp một giao diện cấp thấp để Windows 2000 có thể chạy trên các nền phần cứng khác nhau. HAL làm ẩn các chi tiết phần cứng, như: các giao diện I/O, các điều khiển ngắt và các cơ chế truyền thông giữa các processor trong hệ thống multiprocessor, với bất kỳ một hàm nào trong cả các kiến trúc cụ thể và các máy phụ thuộc.
Trong Windows 2000 có nhiều tập tin Hal*.dll, mỗi tập tin hỗ trợ cho một hệ thống máy tính nào đó. Hal.dll hỗ trợ cho các PC chuẩn, Halmps.dll hỗ trợ cho các PC Multiprocessor, …
❑ Device Drivers:
Các Device Driver (*.sys) là các modun kernel, nó là giao diện giữa thành phần quản lý I/O và các phần cứng có liên quan. Các device driver không thao tác trực tiếp trên phần cứng, nó chỉ gọi các hàm trong HAL để giao tiếp với phần cứng. Windows 2000 có các loại Divice Driver sau đây:
∙ Các hardware device driver thao tác phần cứng, sử dụng HAL, để ghi/đọc trên các thiết bị vật lý hoặc mạng. Loại này bao gồm: các điều khiển bus, các điều khiển thiết bị giao tiếp với người sử dụng, các điều khiển thiết bị lưu trữ khối, …
∙ Các file system driver là các điều khiển mà Windows 2000 dùng nó để truy cập các file trong hệ thống.
∙ …
❑ Kernel Mode Drivers:
Kernel Mode Drivers cũng được cài đặt như là một thành phần, nó chứa tất cả các chức năng cần thiết. Nó gồm có: WMD (Windows Drive Model) driver, cùng với nhiều driver để hỗ trợ cho các yêu cầu của các thiết bị cụ thể.
I.14. Hệ điều hành Linux
Linux là hệ điều hành miễn phí được xây dựng từ hệ điều hành Unix. Nó được phát triển bởi Linus Torvalds, một sinh viên của trường Đại học Hensinki. Linus chỉ chịu trách nhiệm tạo ra hệ thống kernel. Kernel là phần lõi của hệ điều hành, nó chịu trách nhiệm thực hiện các tác vụ của hệ thống. Linux bây giờ như một tập các phần mềm mà trong đó bao gồm kernel và các thành phần khác để nó trở thành một hệ điều hành hoàn chỉnh. Một trong những nguyên nhân làm cho Linux được nhiều người biết đến là nó được cung cấp miễn phí với mã nguồn mở.
Hình vẽ 1.13 dưới đây cho thấy cấu trúc của hệ điều hành Unix. Hình vẽ cho thấy hệ điều hành Linux được chia thành 2 cấp: User Level (cấp người sử dụng) và Kernel Level (cấp lõi).
⮚ Kernel là cấp đặc quyền, ở đây không có giới hạn nào đối với kernel của hệ thống. Kernel có thể sử dụng tất cả các lệnh của vi xử lý, điều khiển toàn bộ bộ nhớ và truyền thông trực tiếp đến tất cả các thiết bị ngoại vi.
⮚ User là cấp không có đặc quyền, tất cả các chương trình của người sử dụng phải hoạt động ở cấp này. Ở đây các tiến trình không thể thực hiện tất cả các lệnh của vi xử lý, không thể truy cập trực tiếp vào hệ thống phần cứng và nó chỉ được quyền sử dụng không gian nhớ đã được cấp phát. Các tiến trình ở đây chỉ có thể thực hiện các thao tác trong môi trường của riêng nó mà không làm ảnh hưởng đến các tiến trình khác và nó có thể bị ngắt bất cứ lúc nào. Các tiến trình hoạt động trong User Level không thể truy cập trực tiếp tài nguyên của hệ thống mà nó phải thông qua giao diện lời gọi hệ thống (System call Interface). Một lời gọi hệ thống là một yêu cầu được gởi từ tiến trình của chương trình người sử dụng đến Kernel, Kernel sẽ xử lý yêu cầu trong chế độ kernel sau đó trả kết quả về lại cho tiến trình để tiến trình tiếp tục thực hiện.
User Programs
Trap
Libraries
User Level
Kernel Level
System Call Interface
File Subsystem Inter Processor
Process Communication
⮚ Sau đây là một vài đặc điểm của Linux:
∙ Miễn phí (Free): Linux là một hệ điều hành được cung cấp miễn phí trên Internet, chúng ta không phải trả bất kỳ một chi phí nào cho việc download nó. Linux được cung cấp cùng với các phâìn mềm chạy trên nó. ∙ Mã nguồn mở (Open Source): Điều này có nghĩa người sử dụng không chỉ sử dụng hệ điều hành và thực hiện các chương trình mà còn có thể xem và sửa đổi mã nguồn của nó, để phát triển nó theo từng mục đích cụ thể của người sử dụng.
∙ Yêu cầu phần cứng (Hardware): Linux có thể chạy trên hầu hết các phần cứng hiện có, nó có thể hoạt động trên các vi xử lý: 386, 486, Pentium MMX, Pentium II, Sparc, Dec Alpha hoặc Motorola 68000.
∙ Đa tác vụ (Multi-Tasking): Linux là hệ điều hành đa tác vụ, tức là một người sử dụng có thể chạy nhiều chương trình tại cùng một thời điểm. Mỗi tác vụ là một tiến trình. Theo cách này người sử dụng không cần phải đợi cho
một tiến trình kế thúc hợp lệ để khởi động một tiến trình khác.
∙ Đa người sử dụng (Multi-User): Điều này có nghĩa có nhiều hơn một người sử dụng có thể sử dụng hệ thống tại cùng một thời điểm. Khái niệm multi user xuất phát trực tiếp từ khía cạnh multi-tasking. Hệ thống có thể điều khiển nhiều hơn một người sử dụng tại cùng một thời điểm giống như cách mà nó điều khiển nhiều hơn một công việc.
∙ Hỗ trợ đa vi xử lý (Multi Processor Support): Linux có thể điều hành các hệ thống máy tính có nhiều hơn một vi xử lý.
∙ Máy chủ web (Web Server): Linux có thể được sử dụng để chạy như là một web server, và đáp ứng các giao thức ứng dụng như là HTTP hoặc FTP.
∙ Hỗ trợ mạng TCP/IP (TCP/IP Networking Support): Hỗ trợ mạng TCP/IP được xây dựng trong chính kernel của Linux. Linux một trong các hệ điều hành mạng tốt nhất. Nó bao gồm các chương trình như là: Telnet, Ftp, Rlogin, Rsh và nhiều chương trình khác.
∙ Hỗ trợ lập trình (Programming Support): Linux cung cấp hỗ trợ lập trình cho Fortran, C, C++, Tcl/Tk, Perl và nhiều ngôn ngữ lập trình khác. ∙ Độ an toàn cao (High Level Security): Một trong những thuận lợi
chính của Linux đó là nó cung cấp một sự an toàn cao cấp bằng cách sử dụng sự xác thực người sử dụng. Nó cũng lưu trữ password trong dạng thức được mã hoá, password một khi đã được mã hoá thì không thể giải mã. Linux cũng bao gồm hệ thống file an toàn, nó được mở rộng từ hệ thống file đang tồn tại.
Chương II
QUẢN LÝ TIẾN TRÌNH
Tất cả các hệ điều hành đa chương, từ các hệ điều hành đơn người sử dụng đến các hệ điều hành có thể hỗ trợ đến hàng ngàn người sử dụng, đều phải xây dụng dựa trên khái niệm tiến trình. Vì thế, một yêu cầu quan trọng trong thiết kế hệ điều hành là thành phần quản lý tiến trình của hệ điều hành phải đáp ứng tất cả những gì liên quan đến tiến trình:
∙ Hệ điều hành phải cho phép thực hiện nhiều tiến trình đồng thời để khai thác tối đa thời gian xử lý của processor nhưng cũng cung cấp được thời gian hồi đáp hợp lý.
∙ Hệ điều hành phải cấp phát tài nguyên để tiến trình hoạt động một cách hiệu quả với một chính sách hợp lý nhưng không xảy ra tình trạng tắc nghẽn trong hệ thống.
∙ Hệ điều hành có thể được yêu cầu để hỗ trợ truyền thông liên tiến trình và người sử dụng tạo ra tiến trình.
Hệ điều hành phải có nhiệm vụ tạo ra tiến trình, điều khiển sự hoạt động của tiến trình và kết thúc tiến trình.
Một số hệ điều hành phân biệt hai khái niệm tiến trình và tiểu trình. Tiến trình liên quan đến quyền sở hữu tài nguyên, tiểu trình liên quan đến sự thực hiện chương trình.
Trong các hệ điều hành đa chương, có nhiều tiến trình tồn tại trên bộ nhớ chính, các tiến trình này luân phiên giữa hai trạng thái: sử dụng processor và đợi thực hiện vào/ra hay một vài sự kiện nào đó xảy ra.
Tất cả những vấn đề trên sẽ được làm sáng tỏ trong chương này. I.15. Tổng quan về tiến trình
I.1.9. Tiến trình và các loại tiến trình
⮚ Tiến trình (process): Trong chương I chúng ta đã có khái niệm về tiến trình: Tiến trình là một bộ phận của một chương trình đang thực hiện, đơn vị thực hiện tiến trình là processer. Ở đây chúng tôi nhấn mạnh thêm rằng: Vì tiến trình là một bộ phận của chương trình nên tương tự như chương trình tiến trình cũng sở hữu một con trỏ lệnh, một con trỏ stack, một tập các thanh ghi, một không gian địa chỉ trong bộ nhớ chính và tất cả các thông tin cần thiết khác để tiến trình có thể hoạt động được.
Khái niệm trên đây mang tính trực quan, để thấy được bản chất của tiến trình các chuyên gia về hệ điều hành đã đưa ra nhiều định nghĩa khác nhau về tiến trình, ở đây chúng tôi nêu ra hai định nghĩa để các bạn tham khảo. Định nghĩa của Saltzer: Tiến trình là một chương trình do một processor logic thực hiện. Định nghĩa của Horning & Rendell: Tiến trình là một quá trình chuyển từ trạng thái này sang trạng thái khác dưới tác động của hàm hành động, xuất phát từ một trạng thái ban đầu nào đó.
Định nghĩa của Saltzer cho thấy, trên góc độ thực hiện thì tiến trình hoàn toàn tương tự chương trình, chỉ khác ở chỗ: tiến trình do processor logic chứ không phải processor vật lý thực hiện. Điều này sẽ được làm sáng tỏ trong phần mô tả về tiến trình sau đây. Định nghĩa của Horning & Rendell cho thấy trong quá trình hoạt
động của tiến trình là quá trình chuyển từ trạng thái này sang trạng thái khác nhưng sự chuyển đổi này không phải do chính bản thân tiến trình mà là do sự tác động từ bên ngoài, cụ thể ở đây là bộ phận điều phối tiến trình của hệ điều hành. Điều này sẽ được làm sáng tỏ trong phần mô tả về các trạng thái tiến trình sau đây.
⮚ Các loại tiến trình: Các tiến trình trong hệ thống có thể chia thành hai loại: tiến trình tuần tự và tiến trình song song. Tiến trình tuần tự là các tiến trình mà điểm khởi tạo của nó là điểm kết thúc của tiến trình trước đó. Tiến trình song song là các tiến trình mà điểm khởi tạo của tiến trình này mằn ở thân của các tiến trình khác, tức là có thể khởi tạo một tiến trình mới khi các tiến trình trước đó chưa kết thúc. Tiến trình song song được chia thành nhiều loại:
∙ Tiến trình song song độc lập: là các tiến trình hoạt động song song nhưng không có quan hệ thông tin với nhau, trong trường hợp này hệ điều hành phải thiết lập cơ chế bảo vệ dữ liệu của các tiến trình, và cấp phát tài nguyên cho các tiến trình một cách hợp lý.
∙ Tiến trình song song có quan hệ thông tin: trong quá trình hoạt động các tiến trình thường trao đổi thông tin với nhau, trong một số trường hợp tiến trình gởi thông báo cần phải nhận được tín hiệu từ tiến trình nhận để tiếp tục, điều này dễ dẫn đến bế tắc khi tiến trình nhận tín hiệu không ở trong trạng thái nhận hay tiến trình gởi không ở trong trạng thái nhận thông báo trả lời.
∙ Tiến trình song song phân cấp: Trong qua trình hoạt động một tiến trình có thể khởi tạo các tiến trình khác hoạt động song song với nó, tiến trình khởi tạo được gọi là tiến trình cha, tiến trình được tạo gọi là tiến trình con. Trong mô hình này hệ điều hành phải giải quyết vấn đề cấp phát tài nguyên cho các tiến trình con. Tiến trình con nhận tài nguyên ở đâu, từ tiến trình cha hay từ hệ thống. Để giải quyết vấn đề này hệ điều hành đưa ra 2 mô hình quản lý tài nguyên: Thứ nhất, mô hình tập trung, trong mô hình này hệ điều hành chịu trách nhiệm phân phối tài nguyên cho tất cả các tiến trình trong hệ thống. Thứ hai, mô hình phân tán, trong mô hình này hệ điều hành cho phép tiến trình con nhận tài nguyên từ tiến trình cha, tức là tiến trình khởi tạo có nhiệm vụ nhận tài nguyên từ hệ điều hành để cấp phát cho các tiến trình mà nó tạo ra, và nó có nhiệm vụ thu hồi lại tài nguyên đã cấp phát trả về cho hệ điều hành trước khi kết thúc.
∙ Tiến trình song song đồng mức: là các tiến trình hoạt động song song sử dụng chung tài nguyên theo nguyên tắc lần lượt, mỗi tiến trình sau một khoảng thời gian chiếm giữ tài nguyên phải tự động trả lại tài nguyên cho tiến trình kia.
Các tiến trình tuần tự chỉ xuất hiện trong các hệ điều hành đơn nhiệm đa chương, như hệ điều hành MS_DOS, loại tiến trình này tồn tại nhiều hạn chế, điển hình nhất là không khai thác tối đa thời gian xử lý của processor. Các tiến trình song song xuất hiện trong các hệ điều hành đa nhiệm đa chương, trên cả hệ thống uniprocessor và multiprocessor. Nhưng sự song song thực, chỉ có ở các hệ thống
multiprocessor, trong hệ thống này mỗi processor chịu trách nhiệm thực hiện một tiến trình. Sự song song trên các hệ thống uniprocessor là sự song song giả, các tiến trình song song trên hệ thống này thực chất là các tiến trình thay nhau sử dụng processor, tiến trình này đang chạy thì có thể dừng lại để nhường processor cho tiến trình khác chạy và sẽ tiếp tục lại sau đó khi có được processor. Đây là trường hợp mà ở trên ta cho rằng: điểm khởi tạo của tiến trình này nằm ở thân của tiến trình khác.
Hình vẽ sau đây minh họa sự khác nhau, về mặt thực hiện, giữa các tiến trình song song/ đồng thời trong hệ thống uniprocessor với các tiến trình song song/ đồng thời trong hệ thống multiprocessor.
P1
P2
P3 Time
a. Trong hệ thống uniprocessor
P1
P2
P3 Time
b. Trong hệ thống Multiprocessor
Hình 2.1: Sự thực hiện đồng thời của các tiến trình trong
hệ thống uniprocessor (a) và hệ thống multiprocessor (b).
Trong tài liệu này chúng ta chỉ khảo sát sự hoạt động của các tiến trình song song (hay đồng thời) trên các hệ thống uniprocessor.
Đối với người sử dụng thì trong hệ thống chỉ có hai nhóm tiến trình. Thứ nhất, là các tiến trình của hệ điều hành. Thứ hai, là các tiến trình của chương trình người sử dụng. Các tiến trình của hệ điều hành hoạt động trong chế độ đặc quyền, nhờ đó mà nó có thể truy xuất vào các vùng dữ liệu được bảo vệ của hệ thống. Trong khi đó các tiến trình của chương trình người sử dụng hoạt động trong chế độ không đặc quyền, nên nó không thể truy xuất vào hệ thống, nhờ đó mà hệ điều hành được bảo vệ. Các tiến trình của chương trình người sử dụng có thể truy xuất vào hệ thống thông qua các tiến trình của hệ điều hành bằng cách thực hiện một lời gọi hệ thống.
I.1.10. Mô hình tiến trình
Đa số các hệ điều hành đều muốn đưa sự đa chương, đa nhiệm vào hệ thống. Tức
là, trong hệ thống có thể có nhiều chương trình hoạt động đồng thời (concurrence) với nhau. Về nguyên tắc, để thực hiện được điều này thì hệ thống phải có nhiều processor, mỗi processor có nhiệm vụ thực hiện một chương trình, nhưng mong muốn của hệ điều hành cũng như người sử dụng là thực hiện sự đa chương trên các hệ thống chỉ có một processor, và trên thực tế đã xuất hiện nhiều hệ điều hành thực hiện được điều này, hệ điều hành windows9x, windowsNT/2000 chạy trên máy tính cá nhân là một ví dụ. Để thực hiện được điều này hệ điều hành đã sử dụng mô hình tiến trình để tạo ra sự song song giả hay tạo ra các processor logic từ processor vật lý. Các processor logic có thể hoạt động song song với nhau, mỗi processor logic chịu trách nhiệm thực hiện một tiến trình.
Trong mô hình tiến trình hệ điều hành chia chương trình thành nhiều tiến trình, khởi tạo và đưa vào hệ thống nhiều tiến trình của một chương trình hoặc của nhiều chương trình khác nhau, cấp phát đầy đủ tài nguyên (trừ processor) cho tiến trình và đưa các tiến trình sang trạng thái sẵn sàng. Hệ điều hành bắt đầu cấp processor cho một tiến trình trong số các tiến trình ở trạng thái sẵn sàng để tiến trình này hoạt động, sau một khoảng thời gian nào đó hệ điều hành thu hồi processor của tiến trình này để cấp cho một tiến trình sẵn sàng khác, sau đó hệ điều hành lại thu hồi processor từ tiến trình mà nó vừa cấp để cấp cho tiến trình khác, có thể là tiến trình mà trước đây bị hệ điều hành thu hồi processor khi nó chưa kết thúc, và cứ như thế cho đến khi tất cả các tiến trình mà hệ điều hành khởi tạo đều hoạt động và kết thúc được. Điều đáng chú ý trong mô hình tiến trình này là khoảng thời gian chuyển processor từ tiến trình này sang tiến trình khác hay khoảng thời gian giữa hai lần được cấp phát processor của một tiến trình là rất nhỏ nên các tiến trình có cảm giác luôn được sở hữu processor (logic) hay hệ thống có cảm giác các tiến trình/ chương trình hoạt động song song nhau. Hiện tượng này được gọi là sự song song giả.
Giả sử trong hệ thống có 3 tiến trình sẵn sàng P1, P2, P3 thì quá trình chuyển processor giữa 3 tiến trình này có thể minh họa như sau:
Thời điểm Trạng thái các tiến trình
t1 P1: được cấp processor
t2 P1: bị thu hồi processor (khi chưa kết thúc)
P3: được cấp processor
t3 P3: bị thu hồi processor (khi chưa kết thúc)
P1: được cấp processor
t4 P1: kết thúc và trả lại processor
P2: được cấp processor
t5 P2: kết thúc và trả lại processor
P3: được cấp processor
t6 P3: kết thúc và trả lại processor
Hình sau đây minh họa quá trình thực hiện của 3 tiến trình P1, P2, P3 ở trên: P1
P2
P3Time
t1 t2 t3 t4 t5t6
Hình 2.2: Sự hoạt động “song song” của các tiến trình P1, P2, P3
uniprocessor
Chúng ta đều biết, chức năng cở bản của processor là thực hiện các chỉ thị máy (machine instrustion) thường trú trong bộ nhớ chính, các chỉ thị này được cung cấp từ một chương trình, chương trình bao gồm một dãy tuần tự các chỉ thị. Và theo trên, tiến trình là một bộ phận của chương trình, nó cũng sở hữu một tập lệnh trong bộ nhớ chính, một con trỏ lệnh,… Nên xét về bản chất, thì việc chuyển processor từ tiến trình này sang tiến trình khác thực chất là việc điều khển processor để nó thực hiện xen kẽ các chỉ thị bên trong tiến trình. Điều này có thể thực hiện dễ dàng bằng cách thay đổi hợp lý giá trị của con trỏ lệnh, đó chính là cặp thanh ghi CS:IP trong các processor thuộc kiến trúc Intel, để con trỏ lệnh chỉ đến các chỉ thị cần thực hiện trong các tiến trình. Để thấy rõ hơn điều này ta hãy xem ví dụ sau đây:
Giả sử hệ thống cần thực hiện đồng thời 3 tiến trình P1, P2, P3, bắt đầu từ tiến trình P1. Các chỉ thị của các tiến trình này được nạp vào bộ nhớ tại các địa chỉ như sau:
Tiến trình P1: Tiến trình P2: Tiến trình P3:
a + 0 b + 0 c + 0
a + 1 b + 2 c + 1
a + 3 b + 3 c + 4
a + 5 c + 6 Trong đó: a: là địa chỉ bắt đầu của chương trình của tiến trình P1 b: là địa chỉ bắt đầu của chương trình của tiến trình P2
c: là địa chỉ bắt đầu của chương trình của tiến trình P3
Thì giá trị của con trỏ lệnh, chính xác là giá trị cặp thanh ghi CS:IP, lần lượt là: a + 0, b + 0, c + 0, a + 1, b + 2, c + 1, a + 3, b + 3, c + 4, a + 5, c + 6. Tức là, processor thực hiện xen kẽ các chỉ thị của 3 tiến trình P1, P2, P3 từ lệnh đầu tiên đến lệnh cuối cùng, cho đến khi tất cả các chỉ thị của 3 tiến trình đều được thực hiện. Nhưng khoảng thời gian từ khi con trỏ lệnh = a + 0 đến khi = a + 1, hay từ khi = b + 0 đến khi = b + 2, … là rất nhỏ, nên hệ thống có “cảm giác” 3 tiến trình P1, P2, P3 hoạt động đồng thời với nhau.
Ví dụ trên đây cho ta thấy bản chất của việc thực hiện song song (hay đồng thời) các tiến trình trên các hệ thống uniprocessor.
Rõ ràng với mô hình tiến trình hệ thống có được 2 điều lợi:
∙ Tiết kiệm được bộ nhớ: vì không phải nạp tất cả chương trình vào bộ nhớ mà chỉ nạp các tiến trình cần thiết nhất, sau đó tùy theo yêu cầu mà có thể nạp tiếp các tiến trình khác.
∙ Cho phép các chương trình hoạt động song song nên tốc độ xử lý của toàn hệ thống tăng lên và khai thác tối đa thời gian xử lý của processor. Việc chọn thời điểm dừng của tiến trình đang hoạt động (đang chiến giữ processor) để thu hồi processor chuyển cho tiến trình khác hay việc chọn tiến trình tiếp theo nào trong số các tiến trình đang ở trạng thái sẵn sàng để cấp processor là những vấn đề khá phức tạp đòi hỏi hệ điều hành phải có một cơ chế điều phối thích hợp thì mới có thể tạo ra được hiệu ứng song song giả và sử dụng tối ưu thời gian xử lý của processor. Bộ phận thực hiện chức năng này của hệ điều hành được gọi là bộ điều phối (dispatcher) tiến trình.
I.1.11. Tiểu trình và tiến trình
⮚ Tiểu trình: Thông thường mỗi tiến trình có một không gian địa chỉ và một dòng xử lý. Nhưng trong thực tế có một số ứng dụng cần nhiều dòng xử lý cùng chia sẻ một không gian địa chỉ tiến trình, các dòng xử lý này có thể hoạt động song song với nhau như các tiến trình độc lập trên hệ thống. Để thực hiện được điều này các hệ điều hành hiện nay đưa ra một cơ chế thực thi (các chỉ thị trong chương trình) mới, được gọi là tiểu trình.
Tiểu trình là một đơn vị xử lý cơ bản trong hệ thống, nó hoàn toàn tương tự như tiến trình. Tức là nó cũng phải xử lý tuần tự các chỉ thị máy của nó, nó cũng sở hữu con trỏ lệnh, một tập các thanh ghi, và một không gian stack riêng.
Một tiến trình đơn có thể bao gồm nhiều tiểu trình. Các tiểu trình trong một tiến trình chia sẻ một không gian địa chỉ chung, nhờ đó mà các tiểu trình có thể chia sẻ các biến toàn cục của tiến trình và có thể truy xuất lên các vùng nhớ stack của nhau.
Các tiểu trình chia sẻ thời gian xử lý của processor giống như cách của tiến trình, nhờ đó mà các tiểu trình có thể hoạt động song song (giả) với nhau. Trong quá trình thực thi của tiểu trình nó cũng có thể tạo ra các tiến trình con của nó. ⮚ Đa tiểu trình trong đơn tiến trình: Điểm đáng chú ý nhất của mô hình tiểu trình là: có nhiều tiểu trình trong phạm vi một tiến trình đơn. Các tiến trình đơn này có thể hoạt động trên các hệ thống multiprocessor hoặc uniprocessor. Các hệ điều hành khác nhau có cách tiếp cận mô hình tiểu trình khác nhau. Ở đây chúng ta tiếp cận mô hình tiểu trình từ mô hình tác vụ (Task), đây là các tiếp cận của windows NT và các hệ điều hành đa nhiệm khác. Trong các hệ điều hành này tác vụ được
định nghĩa như là một đơn vị của sự bảo vệ hay đơn vị cấp phát tài nguyên. Trong hệ thống tồn tại một không gian địa chỉ ảo để lưu giữ tác vụ và một cơ chế bảo vệ sự truy cập đến các file, các tài nguyên Vào/Ra và các tiến trình khác (trong các thao tác truyền thông liên tiến trình).
Trong phạm vị một tác vụ, có thể có một hoặc nhiều tiểu trình, mỗi tiểu trình bao gồm: Một trạng thái thực thi tiểu trình (running, ready,…). Một lưu trữ về ngữ cảnh của processor khi tiểu trình ở trạng thái not running (một cách để xem tiểu trình như một bộ đếm chương trình độc lập hoạt động trong phạm vi tác vụ). Các thông tin thống kê về việc sử dụng các biến cục bộ của tiểu trình. Một stack thực thi. Truy xuất đến bộ nhớ và tài nguyên của tác vụ, được chia sẻ với tất cả các tiểu trình khác trong tác vụ.
Trong các ứng dụng server, chẳng hạn như ứng dụng file server trên mạng cục bộ, khi có một yêu cầu hình thành một file mới, thì một tiểu trình mới được hình thành từ chương trình quản lý file. Vì một server sẽ phải điều khiển nhiều yêu cầu, có thể đồng thời, nên phải có nhiều tiểu trình được tạo ra và được giải phóng trong, có thể đồng thời, một khoảng thời gian ngắn. Nếu server là một hệ thống multiprocessor thì các tiểu trình trong cùng một tác vụ có thể thực hiện đồng thời trên các processor khác nhau, do đó hiệu suất của hệ thống tăng lên. Sự hình thành các tiểu trình này cũng thật sự hữu ích trên các hệ thống uniprocessor, trong trường hợp một chương trình phải thực hiện nhiều chức năng khác nhau. Hiệu quả của việc sử dụng tiểu trình được thấy rõ trong các ứng dụng cần có sự truyền thông giữa các tiến trình hoặc các chương trình khác nhau.
Các thao tác lập lịch và điều phối tiến trình của hệ điều hành thực hiện trên cơ sở tiểu trình. Nhưng nếu có một thao tác nào đó ảnh hưởng đến tấ cả các tiểu trình trong tác vụ thì hệ điều hành phải tác động vào tác vụ.
Vì tất cả các tiểu trình trong một tác vụ chia sẻ cùng một không gian địa chỉ, nên tất cả các tiểu trình phải được đưa vào trạng thái suspend tại cùng thời điểm. Tương tự, khi một tác vụ kết thúc thì sẽ kết thúc tất cả các tiểu trình trong tác vụ đó. Trạng thái suspend sẽ được giải thích ngay sau đây.
I.1.12. Các trạng thái tiến trình
Từ khi được đưa vào hệ thống cho đến khi kết thúc tiến trình tồn tại ở các trạng thái khác nhau. Trạng thái của tiến trình tại một thời điểm được xác định bởi hoạt động hiện thời của tiến trình tại thời điểm đó.
⮚ Tiến trình hai trạng thái: Một số ít hệ điều hành chỉ cho phép tiến trình tồn tại ở một trong hai trạng thái: Not Running và Running. Khi hệ điều hành tạo ra một tiến trình mới, hệ điều hành đưa tiến trình đó vào hệ thống ở trạng thái Not Running, tiến trình ở trạng thái này để chờ được chuyển sang trạng thái Running. Vì một lý do nào đó, tiến trình đang thực hiện bị ngắt thì bộ điều phối tiến trình của
Dispatch
hệ điều hành sẽ thu hồi lại processor của tiến trình này và chọn một tiến trình ở trạng thái Not running để cấp processor cho nó và chuyển nó sang trạng thái Running. Tiến trình bị thu hồi processor sẽ được chuyển về lại trạng thái Not running.
Tại một thời điểm xác định chỉ có duy nhất một tiến trình ở trạng thái Runnig, nhưng có thể có nhiều tiến trình ở trạng thái Not running, các tiến trình ở trạng thái Not running được chứa trong một hàng đợi (Queue). Tiến trình đang ở trạng thái Running bị chuyển sang trạng thái Not running sẽ được đưa vào hàng đợi. Hình vẽ sau đây mô tả việc chuyển trạng thái tiến trình trong các hệ điều hành sử dụng 2 trạng thái tiến trình.
Enter
Queue
Dispatch
Pause
Exit
Processor
Hình 2.3.b: Sơ đồ chuyển tiến trình vào hàng đợi
⮚ Tiến trình ba trạng thái: Đa số hệ điều hành đều cho phép tiến trình tồn tại ở một trong ba trạng thái, đó là: ready, running, blocked:
∙ Trạng thái Ready (sẵn sàng): Ngay sau khi khởi tạo tiến trình, đưa tiến trình vào hệ thống và cấp phát đầy đủ tài nguyên (trừ processor) cho tiến trình, hệ điều hành đưa tiến trình vào trạng thái ready. Hay nói cách khác, trạng thái ready là trạng thái của một tiến trình trong hệ thống đang chờ được cấp processor để bắt đầu thực hiện.
∙ Trạng thái Running (thực hiện): Là trạng thái mà tiến trình đang được sở hữu processor để hoạt động, hay nói cách khác là các chỉ thị của tiến trình đang được thực hiện/ xử lý bởi processor.
∙ Trạng thái Blocked (khoá): Là trạng thái mà tiến trình đang chờ để được cấp phát thêm tài nguyên, để một sự kiện nào đó xảy ra, hay một quá trình vào/ra kết thúc.
Quá trình chuyển trạng thái của các tiến trình trong được mô tả bởi sơ đồ
sau:
New
2
1
4
Ready
3
Running
Blocked
6 5
Hình 2.4.a: Sơ đồ chuyển trạng thái tiến trình
Exit
Trong đó:
1. (Admit) Tiến trình được khởi tạo, được đưa vào hệ thống, được cấp phát đầy đủ tài nguyên chỉ thiếu processor.
2. (Dispatch) Tiến trình được cấp processor để bắt đầu thực hiện/ xử lý. 3. (Release) Tiến trình hoàn thành xử lý và kết thúc.
4. (Time_out) Tiến trình bị bộ điều phối tiến trình thu hồi processor, do hết thời gian được quyền sử dụng processor, để cấp phát cho tiến trình khác. 5. (Event wait) Tiến trình đang chờ một sự kiện nào đó xảy ra hay đang chờ một thao vào/ra kết thúc hay tài nguyên mà tiến trình yêu cầu chưa được hệ điều hành đáp ứng.
6. (Event Occurs) Sự kiện mà tiến trình chờ đã xảy ra, thao tác vào/ra mà tiến trình đợi đã kết thúc, hay tài nguyên mà tiến trình yêu cầu đã được hệ điều hành đáp ứng,
Bộ phận điều phối tiến trình thu hồi processor từ một tiến trình đang thực hiện trong các trường hợp sau:
• Tiến trình đang thực hiện hết thời gian (time-out) được quyền sử dụng processor mà bộ phận điều phối dành cho nó.
• Có một tiến trình mới phát sinh và tiến trình mới này có độ ưu tiên cao hơn tiến trình hiện tại.
• Có một tiến trình mới phát sinh và tiến trình này mới cần một khoảng thời gian của processor nhỏ hơn nhiều so với khoảng thời gian còn lại mà tiến trình hiện tại cần processor.
Tại một thời điểm xác định trong hệ thống có thể có nhiều tiến trình đang ở trạng thái Ready hoặc Blocked nhưng chỉ có một tiến trình ở trạng thái Running. Các tiến trình ở trạng thái Ready và Blocked được chứa trong các hàng đợi (Queue)
riêng.
Release AdmitReady QueueDispatch Processor
Time-out
Event Event Wait
Có nhiều lý do để một tiến trình đang ở trạng thái running chuyển sang trạng thái blocked, do đó đa số các hệ điều hành đều thiết kế một hệ thống hàng đợi gồm nhiều hàng đợi, mỗi hành đợi dùng để chứa những tiến trình đang đợi cùng một sự kiện nào đó.
⮚ Tiến trình 4 trạng thái: Trong môi trường hệ điều hành đa nhiệm thì việc tổ chức các Queue để lưu các tiến trình chưa thể hoạt động là cần thiết, nhưng nếu tồn tại quá nhiều tiến trình trong Queue, hay chính xác hơn trong bộ nhớ chính, sẽ dẫn đến trình trạng lãng phí bộ nhớ, không còn đủ bộ nhớ để nạp các tiến trình khác khi cần thiết. Mặt khác nếu các tiến trình trong Queue đang chiếm giữ tài nguyên của hệ thống, mà những tài nguyên này lại là những tài nguyên các tiến trình khác đang cần, điều này dẫn đến tình trạng sử dụng tài nguyên không hợp lý, làm cho hệ thống thiếu tài nguyên (thực chất là thừa) trầm trọng và có thể làm cho hệ thống tắc nghẽn. Với những lý do trên các hệ điều hành đa nhiệm thiết kế thêm một trạng thái tiến trình mới, đó là trạng thái Suspend (tạm dừng). Trạng thái này rất cần thiết cho các hệ thống sử dụng kỹ thuật Swap trong việc cấp phát bộ nhớ cho các tiến trình. Khái niệm Swap sẽ được đề cập đến trong chương Quản lý bộ nhớ của tài liệu này.
New
Running
Activate
Ready
End
Suspend Blocked
Suspend
Hình 2.5.a: Sơ đồ chuyển trạng thái tiến trình có suspend
Trạng thái Suspend là trạng thái của một tiến trình khi nó đang được lưu trữ trên bộ nhớ phụ, hay chính xác hơn đây là các tiến trình đang ở trong trạng thái blocked và/hoặc ready bị hệ điều hành chuyển ra đĩa để thu hồi lại không gian nhớ đã cấp cho tiến trình hoặc thu hồi lại tài nguyên đã cấp cho tiến trình để cấp cho một tiến trình khác đang rất cần được nạp vào bộ nhớ tại thời điểm hiện tại.
⮚ Tiến trình 5 trạng thái: Trong thực tế hệ điều hành thiết kế 2 trạng thái suspend, một trạng thái suspend dành cho các tiến trình từ blocked chuyển đến, trạng thái này được gọi là blocked-suspend và một trạng thái suspend dành cho các tiến trình từ ready chuyển đến, trạng thái này được gọi là ready-suspend.
Tới đây ta có thể hiểu các trạng thái tiến trình như sau:
• Ở trạng thái Ready tiến trình được định vị trong bộ nhớ chính và đang chờ được cấp processor để thực hiện.
• Ở trạng thái Blocked tiến trình được định vị trong bộ nhớ chính và đang đợi một sự kiện hay một quá trình I/O nào đó.
• Ở trạng thái Blocked-suspend tiến trình đang bị chứa trên bộ nhớ phụ (đĩa) và đang đợi một sự kiện nào đó.
• Ở trạng thái Ready-suspend tiến trình đang bị chứa trên bộ nhớ phụ nhưng sẵn sàng thực hiện ngay sau khi được nạp vào bộ nhớ chính.
Admit
Suspend
Admit
New
Ready suspend
Activate Suspend
Ready
Event Occurs
Running
Release Exit
Event Occurs
Blocked suspend
Activate
Blocked
Hình 2.5.b: Sơ đồ chuyển trạng thái tiến trình với 2 suspend
Sau đây chúng ta xem xét sự chuyển trạng thái tiến trình trong sơ đồ trên: 1. Blocked sang Blocked-suspend: nếu không còn tiến trình ready trong bộ nhớ chính và bộ nhớ chính không còn không gian nhớ trống thì phải có ít nhất một tiến trình blocked bị chuyển ra ngoài, blocked-suspend, để dành bộ nhớ cho một tiến trình không bị khoá (not blocked) khác.
2. Blocked-suspend sang Ready-suspend: một tiến trình đang ở trạng thái blocked-suspend được chuyển sang trạng thái ready-suspend khi sự kiện mà nó đợi đã xảy ra.
3. Ready-suspend sang Ready: có 2 lý do để hệ điều hành chọn khi chuyển một tiến trình ở trạng thái ready-suspend sang trạng thái ready: • Không còn tiến trình ready trong bộ nhớ chính, hệ điều hành phải nạp một tiến trình mới vào để nó tiếp tục thực hiện
• Nếu có tiến trình ready-suspend có độ ưu tiên cao hơn so với các tiến trình ready hiện tại thì hệ điều hành có thể chuyển nó sang trạng thái ready để nó nhiều cơ hội để được thực hiện hơn.
4. Ready sang Ready suspend: Hệ điều hành thường chuyển các tiến trình blocked sang suspend hơn là các tiến trình ready, vì các tiến trình ở trạng thái blocked không thể thực hiện ngay lập tức nhưng lại chiếm nhiều không gian bộ nhớ chính hơn so với các tiến trình ở trạng thái ready. Tuy nhiên, nếu việc chọn tiến trình để chuyển sang suspend dựa vào 2 điều kiện: chiếm ít không gian bộ nhớ hơn và có độ ưu tiên thấp hơn thì hệ điều hành có thể chuyển một tiến trình ready sang trạng thái suspend.
Như vậy với việc chuyển tiến trình sang trạng thái suspend hệ điều hành sẽ chủ động hơn trong việc cấp phát bộ nhớ và ngăn chặn các tình huống tắc nghẽn có thể xảy ra do sự tranh chấp về tài nguyên, nhờ vậy mà hệ điều hành tiết kiệm được bộ nhớ, chia sẻ được tài nguyên cho nhiều tiến trình và tăng được mức độ đa chương của hệ thống. Tuy nhiên, để có được những lợi ích trên hệ điều hành đã phải chi phí rất nhiều cho việc tạm dừng tiến trình. Hệ điều hành phải xem xét tiến trình nào được chọn để suspend, khi suspend một tiến trình hệ điều hành phải lưu lại tất cả các thông tin liên quan đến tiến trình đó (con trỏ lệnh, tài nguyên mà tiến trình đã được cấp, ...), hệ điều hành phải lựa chọn thời điển thích hợp để đưa tiến trình ra bộ nhớ ngoài, ... những thao tác đó sẽ làm chậm tốc độ thực hiện của toàn bộ hệ thống. Nhưng dầu sao đi nữa thì hệ điều hành vẫn phải sử dụng trạng thái
suspend vì tăng mức độ đa chương của hệ thống là một trong những mục tiêu lớn của hệ điều hành.
I.1.13. Cấu trúc dữ liệu của khối quản lý tiến trình
Để quản lý các tiến trình và tài nguyên trong hệ thống, hệ điều hành phải có các thông tin về trạng thái hiện thời của mỗi tiến trình và tài nguyên. Trong trường hợp này hệ điều hành xây dựng và duy trì các bảng thông tin về mỗi đối tượng (memory, devices, file, process) mà nó quản lý, đó là các bảng: memory table cho đối tượng bộ nhớ, I/O table cho đối tượng thiết bị vào/ra, file table cho đối tượng tập tin, process table cho đối tượng tiến trình. Memory table được sử dụng để theo dõi cả bộ nhớ thực lẫn bộ nhớ ảo, nó phải bao gồm các thông tin sau: Không gian bộ nhớ chính dành cho tiến trình. Không gian bộ nhớ phụ dành cho tiến trình. Các thuộc tính bảo vệ bộ nhớ chính và bộ nhớ ảo. Các thông tin cần thiết để quản lý bộ nhớ ảo. Ở đây chúng tôi điểm qua một vài thông tin về memory table, là để lưu ý với các bạn rằng: nhiệm vụ quản lý tiến trình và quản lý bộ nhớ của hệ điều hành có quan hệ chéo với nhau, bộ phận quản lý tiến trình cần phải có các thông tin về bộ nhớ để điều khiển sự hoạt động của tiến trình, ngược lại bộ phận quản lý bộ nhớ phải có các thông tin về tiến trình để tổ chức nạp tiến trình vào bộ nhớ, … Điều này cũng đúng với các bộ phận quản lý Vào/ ra và quản lý tập tin. Trong phần trình bày sau đây chúng tôi chỉ đề cập đến Process Table của hệ điều hành.
Để quản lý và điều khiển được một tiến trình, thì hệ điều hành phải biết được vị trí nạp tiến trình trong bộ nhớ chính, phải biết được các thuộc tính của tiến trình cần thiết cho việc quản lý tiến trình của nó:
⮚ Định vị của tiến trình (process location): định vị của tiến trình phụ thuộc vào chiến lược quản lý bộ nhớ đang sử dụng. Trong trường hợp đơn giản nhất, tiến trình, hay chính xác hơn là hình ảnh tiến trình, được lưu giữa tại các khối nhớ liên tục trên bộ nhớ phụ (thường là đĩa), để tiến trình thực hiện được thì tiến trình phải được nạp vào bộ nhớ chính. Do đó, hệ điều hành cần phải biết định vị của mỗi tiến trình trên đĩa và cho mỗi tiến trình đó trên bộ nhớ chính. Trong một số chiến lược quản lý bộ nhớ, hệ điều hành chỉ cần nạp một phần tiến trình vào bộ nhớ chính, phần còn lại vẫn nằm trên đĩa. Hay tiến trình đang ở trên bộ nhớ chính thì có một phần bị swap-out ra lại đĩa, phần còn lại vẫn còn nằm ở bộ nhớ chính. Trong các trường hợp này hệ điều hành phải theo dõi tiến trình để biết phần nào của tiến trình là đang ở trong bộ nhớ chính, phần nào của tiến trình là còn ở trên đĩa.
Đa số các hệ điều hành hiện nay đều sử dụng chiến lược quản lý bộ nhớ mà trong đó không gian địa chỉ của tiến trình là một tập các block, các block này có thể không liên tiếp nhau. Tùy theo chiến lược bộ nhớ sử dụng mà các block này có thể có chiều dài cố định (chiến lược phân phân trang bộ nhớ) hay thay đổi (chiến lược phân đoạn bộ nhớ) hay kết hợp cả hai. Hệ điều hành cho phép không nạp tất cả các trang (page) và/hoặc các đoạn (segment) của tiến trình vào bộ nhớ. Do đó, process
table phải được duy trì bởi hệ điều hành và phải cho biết vị trí của mỗi trang/ đoạn tiến trình trên hệ thống. Những điều trên đây sẽ được làm rõ ở phần chiến lược cấp phát bộ nhớ trong chương Quản lý bộ nhớ của tài liệu này.
⮚ Các thuộc tính của tiến trình: Trong các hệ thống đa chương, thông tin về mỗi tiến trình là rất cần cho công tác quản lý tiến trình của hệ điều hành, các thông tin này có thể thường trú trong khối quản lý tiến trình (PCB: process control block). Các hệ điều hành khác nhau sẽ có cách tổ chức PCB khác nhau, ở đây chúng ta khảo sát một trường hợp chung nhất. Các thông tin trong PCB có thể được chia thành ba nhóm chính:
∙ Định danh tiến trình (PID: process identification): mỗi tiến trình được gán một định danh duy nhất để phân biệt với các tiến trình khác trong hệ thống. Định danh của tiến trình có thể xuất hiện trong memory table, I/O table. Khi tiến trình này truyền thông với tiến trình khác thì định danh tiến trình được sử dụng để hệ điều hành xác định tiến trình đích. Khi tiến trình cho phép tạo ra tiến trình khác thì định danh được sử dụng để chỉ đến tiến trình cha và tiến trình con của mỗi tiến trình. Tóm lại, các định danh có thể lưu trữ trong PCB bao gồm: định danh của tiến trình này, định danh của tiến trình tạo ra tiến trình này, định danh của người sử dụng.
∙ Thông tin trạng thái processor (processor state information): bao gồm các thanh ghi User-visible, các thanh ghi trạng thái và điều khiển, các con trỏ stack. ∙ Thông tin điều khiển tiến trình (process control information): bao gồm thông tin trạng thái và lập lịch, cấu trúc dữ liệu, truyền thông liên tiến trình, quyền
truy cập tiến trình, quản lý bộ nhớ, tài nguyên khởi tạo và tài nguyên sinh ra. PCB là một trong những cấu trúc dữ liệu trung tâm và quan trọng của hệ điều hành. Mỗi PCB chứa tất cả các thông tin về tiến trình mà nó rất cần cho hệ điều hành. Có nhiều modun thành phần trong hệ điều hành có thể read và/hoặc modified PCB như: lập lịch tiến trình, cấp phát tài nguyên cho tiến trình, ngắt tiến trình, vv. Có thể nói các thiết lập trong PCB định nghĩa trạng thái của hệ điều hành.
I.1.14. Các thao tác điều khiển tiến trình
⮚ Khi khởi tạo tiến trình hệ điều hành thực hiện các thao tác sau: ∙ Hệ điều hành gán PID cho tiến trình mới và đưa tiến trình vào danh sách quản lý của hệ thống, tức là, dùng một entry trong PCB để chứa các thông tin liên quan đến tiến trình mới tạo ra này.
∙ Cấp phát không gian bộ nhớ cho tiến trình. Ở đây hệ điều hành cần phải xác định được kích thước của tiến trình, bao gồm code, data và stack. Giá trị kích thước này có thể được gán mặt định dựa theo loại của tiến trình hoặc được gán theo yêu cầu của người sử dụng khi có một công việc (job) được tạo. Nếu một tiến trình được sinh ra bởi một tiến trình khác, thì tiến trình cha có thể chuyển kích thước của
nó đến hệ điều hành trong yêu cầu tạo tiến trình.
∙ Khởi tạo các thông tin cần thiết cho khối điều khiển tiến trình như các PID của tiến trình cha (nếu có), thông tin trạng thái tiến trình, độ ưu tiên của tiến trình, thông tin ngữ cảnh của processor (bộ đến chương trình và các thanh ghi khác), vv.
∙ Cung cấp đầy đủ các tài nguyên cần thiết nhất, trừ processor, để tiến trình có thể vào trạng thái ready được hoặc bắt đầu hoạt động được. ∙ Đưa tiến trình vào một danh sách tiến trình nào đó: ready list, suspend list, waiting list, vv, sao cho phù hợp với chiến lược điều phối tiến trình hiện tại của bộ phận điều phối tiến trình của hệ điều hành.
Khi một tiến trình tạo lập một tiến trình con, tiến trình con có thể được cấp phát tài nguyên bởi chính hệ điều hành, hoặc được tiến trình cha cho thừa hưởng một số tài nguyên ban đầu của nó.
⮚ Khi kết thúc tiến trình hệ điều hành thực hiện các thao tác sau: Khi tiến trình kết thúc xử lý, hoàn thành chỉ thị cuối cùng, hệ điều hành sẽ thực hiện các thao tác sau đây:
∙ Thu hồi tài nguyên đã cấp phát cho tiến trình.
∙ Loại bỏ tiến trình ra khỏi danh sách quản lý của hệ thống.
∙ Huỷ bỏ khối điều khiển tiến trình.
Hầu hết các hệ điều hành đều không cho phép tiến trình con hoạt động khi tiến trình cha đã kết thúc. Trong những trường hợp như thế hệ điều hành sẽ chủ động việc kết thúc tiến trình con khi tiến trình cha vừa kết thúc. ⮚ Khi thay đổi trạng thái tiến trình hệ điều hành thực hiện các bước sau: Khi một tiến trình đang ở trạng thái running bị chuyển sang trạng thái khác (ready, blocked, …) thì hệ điều hành phải tạo ra sự thay đổi trong môi trường làn việc của nó. Sau đây là các bước mà hệ điều hành phải thực hiện đầy đủ khi thay đổi trạng thái tiến trình:
∙ Lưu (save) ngữ cảnh của processor, bao gồm thanh ghi bộ đếm chương trình (PC: program counter) và các thanh ghi khác.
∙ Cập nhật PCB của tiến trình, sao cho phù hợp với trạng thái mới của tiến trình, bao gồm trạng thái mới của tiến trình, các thông tin tính toán, vv. ∙ Di chuyển PCB của tiến trình đến một hàng đợi thích hợp, đế đáp ứng được các yêu cầu của công tác điều phối tiến trình.
∙ Chọn một tiến trình khác để cho phép nó thực hiện.
∙ Cập nhật PCB của tiến trình vừa được chọn thực hiện ở trên, chủ yếu là thay đổi trạng thái của tiến trình đến trạng thái running.
∙ Cập nhật các thông tin liên quan đến quản lý bộ nhớ. Bước này phụ thuộc vào các yêu cầu chuyển đổi địa chỉ bộ nhớ đang được sử dụng. ∙ Khôi phục (Restore) lại ngữ cảnh của processor và thay đổi giá trị của bộ đếm chương trình và các thanh ghi khác sao cho phù hợp với tiến trình được chọn ở trên, để tiến trình này có thể bắt đầu hoạt động được.
Như vậy, khi hệ điều hành chuyển một tiến trình từ trạng thái running (đang chạy) sang một trạng thái nào đó (tạm dừng) thì hệ điều hành phải lưu trữ các thông tin cần thiết, nhất là Program Count, để sau này hệ điều hành có thể cho tiến trình tiếp tục hoạt động trở (tái kích hoạt) lại được. Đồng thời hệ điều hành phải chọn một tiến trình nào đó đang ở trạng thái ready để cho tiến trình này chạy (chuyển tiến trình sang trạng thái running). Tại đây, trong các thao tác phải thực hiện, hệ điều hành phải thực hiện việc thay đổi giá trị của PC, thay đổi ngữ cảnh processor, để PC chỉ đến địa chỉ của chỉ thị đầu tiên của tiến trình running mới này trong bộ nhớ. Đây cũng chính là bản chất của việc thực hiện các tiến trình trong các hệ thống uniprocessor.
I.16. Tài nguyên găng và đoạn găng
II.2.4. Tài nguyên găng (Critical Resource)
Trong môi trường hệ điều hành đa nhiệm - đa chương – đa người sử dụng, việc chia sẻ tài nguyên cho các tiến trình của người sử dụng dùng chung là cần thiết, nhưng nếu hệ điều hành không tổ chức tốt việc sử dụng tài nguyên dung chung của các tiến trình hoạt động đồng thời, thì không những không mang lại hiệu quả khai thác tài nguyên của hệ thống mà còn làm hỏng dữ liệu của các ứng dụng. Và nguy hiểm hơn là việc hỏng dữ liệu này có thể hệ điều hành và ứng dụng không thể phát hiện được. Việc hỏng dữ liệu của ứng dụng có thể làm sai lệch ý nghĩa thiết kế của nó. Đây là điều mà cả hệ điều hành và người lập trình đều không mong muốn.
Các tiến trình hoạt động đồng thời thường cạnh tranh với nhau trong việc sử dụng tài nguyên dùng chung. Hai tiến trình hoạt động đồng thời cùng ghi vào một không gian nhớ chung (một biến chung) trên bộ nhớ hay hai tiến trình đồng thời cùng ghi dữ liệu vào một file chia sẻ, đó là những biểu hiện của sự cạnh tranh về việc sử dụng tìa nguyên dùng chung của các tiến trình. Để các tiến trình hoạt động đồng thời không cạnh tranh hay xung đột với nhau khi sử dụng tài nguyên dùng chung hệ điều hành phải tổ chức cho các tiến trình này được độc quyền truy xuất/ sử dụng trên các tài nguyên dùng chung này.
Những tài nguyên được hệ điều hành chia sẻ cho nhiều tiến trình hoạt động đồng thời dùng chung, mà có nguy cơ dẫn đến sự tranh chấp giữa các tiến trình này khi sử dụng chúng, được gọi là tài nguyên găng. Tài nguyên găng có thể là tài nguyên phần cứng hoặc tài nguyên phần mền, có thể là tài nguyên phân chia được hoặc không phân chia được, nhưng đa số thường là tài nguyên phân chia được như
là: các biến chung, các file chia sẻ.
Các ví dụ sau đây cho thấy hậu quả của việc sử dụng tài nguyên găng trong các chương trình có các tiến trình hoạt động đồng thời:
Ví dụ 1: Giả sử có một chương trình, trong đó có hai tiến trình P1 và P2 hoạt động đồng thời với nhau. Tiến trình P1 phải tăng biến Count lên 1 đơn vị, tiến trình P2 phải tăng biến Count lên 1 đơn vị, với mục đích tăng Count lên được 2 đơn vị. Chương trình có thể thực hiện như sau:
1. Tiến trình P1 ghi nội dung biến toàn cục Count vào biến cục bộ L1 2. Tiến trình P2 ghi nội dung biến toàn cục Count vào biến cục bộ L2 3. Tiến trình P1 thực hiện L1:= L1 + 1 và Count := L1
4. Tiến trình P2 thực hiện L2:= L2 + 1 và Count := L2
Như vậy thoạt nhìn ta thấy rằng chắc chắn Count đã tăng được 2 đơn vị, nhưng trong thực tế có thể Count chỉ tăng được 1 đơn vị. Bởi vì, nếu P1 và P2 đồng thời nhận giá trị của Count (giả sử ban đầu Count = 4) vào L1 và L2, sau đó P1 tăng L1 lên 1 và P2 tăng L2 lên 1 (L1 = 5, L2 = 5), rồi sau đó cả P1 và P2 đồng thời ghi giá trị biến L của nó vào lại Count, thì Count chỉ tăng được 1 đơn vị, Count = 6. Đây là điều mà chương trình không mong muốn nhưng cả chương trình và hệ điều hành đều khó có thể phát hiện được.
Nguyên nhân ở trên là do 2 tiến trình P1 và P2 đồng thời truy xuất biến Count, cả khi nhận giá trị của count, lẫn khi ghi giá trị vào Count. Trong trường hợp này nếu hệ điều hành không cho phép hai tiến trình P1 và P2 đồng thời truy xuất Count, hoặc hệ điều hành cho phép mỗi tiến trình được độc quyền truy xuất Count trong đoạn code sau, thì lỗi trên sẽ không xảy ra.
P1: Begin
L1 := Count;
L1 := L1 + 1;
Count := L1;
End;
P2: Begin
L2 := Count;
L2 := L2 + 1;
Count := L2;
End;
Trong trường hợp này tài nguyên găng là biến count.
Ví dụ 2: Giả sử có một ứng dụng Kế toán, hoạt động trong môi trường đa nhiệm, đa người sử dụng. Mỗi người sử dụng trong môi trường này khi cần thực hiện thao tác rút tiền từ trong tài khoản chung thì phải khởi tạo một tiến trình, tạm gọi là tiến trình rút tiền, tiến trình rút tiền chỉ có thể thực hiện được thao tác rút tiền khi số tiền cần rút nhỏ hơn số tiền còn lại trong tài khoản chung. Trong môi trường này có thể có nhiều người sử dụng đồng thời thực hiện thao tác rút tiền từ tài khoản chung của hệ thống.
Như vậy các tiến trình rút tiền, giả sử có hai tiến trình rút tiền P1 và P1, có
thể hoạt động đồng thời với nhau và cùng chia sẻ không gian nhớ lưu trữ biến Tài khoản, cho biết số tiền còn trong tài khoản dùng chung của hệ thống. Và mỗi tiến trình rút tiền khi muốn rút một khoảng tiền từ tài khoản (Tiền rút) thì phải thực hiện kiểm tra Tài khoản sau đó mới thực hiện việc rút tiền. Tức là mỗi tiến trình rút tiền, khi cần rút tiền đều phải thực hiện đoạn code sau đây:
IF (Tài khoản - Tiền rút >= 0) {kiểm tra tài khoản} Tài khoản := Tài khoản - Tiền rút {thực hiện rút tiền}
Else
Thông báo lỗi {không thể rút tiền}
EndIf;
Nếu tại một thời điểm nào đó:
∙ Trong tài khoản còn 800 ngàn đồng (Tài khoản = 800).
∙ Tiến trình rút tiền P1 cần rút 500 ngàn đồng (Tiền rút = 500). ∙ Tiến trình rút tiền P2 cần rút 400 ngàn đồng (Tiền rút = 400). ∙ Tiến trình P1 và P2 đồng thời rút tiền.
Thì theo nguyên tắc điều trên không thể xảy ra, vì tổng số tiền mà hai tiến trình cần rút lớn hơn số tiền còn lại trong tài khoản (500 + 400 > 800). Nhưng trong môi trường đa nhiệm, đa người sử dụng nếu hệ điều hành không giám sát tốt việc sử dụng tài nguyên dùng chung của các tiến trình hoạt động đồng thời thì điều trên vẫn có thể xảy ra. tức là, cả hai tiến trình P1 và P2 đều thành công trong thao tác rút tiền, mà ứng dụng cũng như hệ điều hành không hề phát hiện. Bởi vì, quá trình rút tiền của các tiến trình P1 và P2 có thể diễn ra như sau:
1. P1 được cấp processor để thực hiện việc rút tiền: P1 thực hiện kiểm tra tài khoản: Tài khoản - Tiền rút = 800 -500 = 300 > 0, P1 ghi nhận điều này và chuẩn bị rút tiền.
2. Nhưng khi P1 chưa kịp rút tiền thì bị hệ điều hành thu hồi lại processor, và hệ điều hành cấp processor cho P2. P1 được chuyển sang trạng thái ready. 3. P2 nhận được processor, được chuyển sang trạng thái running, nó bắt đầu thực hiện việc rút tiền như sau: kiểm tra tài khoản: Tài khoản - Tiền rút
= 800 - 400 = 500 >= 0, P2 ghi nhận điều này và thực hiện rút tiền: Tài khoản = Tài khoản - Tiền rút = 800 - 400 = 400.
4. P2 hoàn thành nhiệm vụ rút tiền, nó kết thúc xử lý và trả lại processor cho hệ điều hành. Hệ điều hành cấp lại processor cho P1, tái kích hoạt lại P1 để nó tiếp tục thao tác rút tiền.
5. Khi được hoạt động trở lại P1 thực hiện ngay việc rút tiền mà không thực hiện việc kiểm tra tài khoản (vì đã kiểm tra trước đó):
Tài khoản = Tài khoản - Tiền rút = 400 - 500 = -100.
6. P1 hoàn thành nhiệm vụ rút tiền và kết thúc tiến trình.
Như vậy cả 2 tiến trình P1 và P2 đều hoàn thành việc rút tiền, không thông báo lỗi, mà không gặp bất kỳ một lỗi hay một trở ngại nào. Nhưng đây là một lỗi nghiêm trọng đối với ứng dụng, vì không thể rút một khoảng tiền lớn hơn số tiền còn lại trong tài khoản, hay Tài khoản không thể nhận giá trị âm.
Nguyên nhân của lỗi này không phải là do hai tiến trình P1 và P2 đồng thời truy xuất biến Tài khoản, mà do hai thao tác: kiểm tra tài khoản và thực hiện rút tiền, của các tiến trình này bị tách rời nhau. Nếu hệ điều hành làm cho hai thao tác này không tách rời nhau thì lỗi này sẽ không xảy ra.
Trong trường hợp này tài nguyên găng là biến Tài khoản.
Ví dụ 3: Giả sử một hệ điều hành đa nhiệm, cung cấp cho các tiến trình của các chương trình người sử dụng một thủ tục Echo. Thủ tục Echo này cho phép các tiến trình nhận một kí tự từ bàn phím rồi đưa kí tự này lên màn hình, mỗi khi gọi nó. Tất cả các tiến trình của chương trình người sử dụng trong hệ thống có thể đồng thời gọi Echo mỗi khi cần đưa một kí tự từ bàn phím lên màn hình. Sau đây là code của thủ tục Echo:
Procedure Echo;
Var
out, in: chracter;
Begin
Input(In, keyboard); {Input là hàm nhập, nó nhận kí tự}
Out:=In; {từ bàn phím đưa vào In. Output là}
Output(Out, Screen); {hàm xuất, nó đưa kí tự từ biến Out} End; {lên màn hình}
Để tiết kiệm bộ nhớ hệ điều hành nạp Echo vào không gian nhớ toàn cục của hệ thống và các tiến trình sẽ chia sẻ không gian nhớ chứa thủ tục Echo này. Sự chia sẻ này là cần thiết và hữu ích, nhưng các tiến trình, hai tiến trình P1 và P2, có thể không đạt được mục tiêu khi gọi Echo, có thể tiến trình P1 gõ kí tự A nhưng màn hình lại xuất hiện kí tự B, B là kí tự của tiến trình P2. Bởi vì hệ thống có thể xảy ra trường hợp sau:
1. Tiến trình P1 gọi thủ tục Echo và bị ngắt ngay lập tức sau khi hàm nhập Input được thực hiện. Tại thời điểm này, kí tự vừa được nhập gần đây nhất là A, được lưu trữ trong biến In.
2. Tiến trình P2 được kích hoạt và gọi thủ tục Echo, và thủ tục được chạy cho đến khi kết thúc. Giả sử đã nhập và xuất kí tự B ra màn hình. 3. Tiến trình P1 được tiếp tục trở lại. Lúc này giá trị A của biến In đã bị ghi đè, có thể là kí tự B của tiến trình P2, biến In = B. Tiến trình P1 tiếp tục
công việc của thủ tục Echo, Out:= In và Out = B. Sau đó hàm xuất Output sẽ đưa giá trị của biến out lên màn hình. Tức là trên màn hình xuất hiện kí tự B. Đây là điều mà tiến trình P1 không hề mong muốn.
Như vậy là kí tự A bị mất, nhưng kí tự B lại xuất hiện hai lần. Bản chất của vấn đề này là nằm ở biến toàn cục In (tài nguyên găng là biến In). Vì hệ điều hành đã để cho nhiều tiến trình hoạt động đồng thời trên hệ thống có quyền truy xuất và truy xuất đồng thời vào biến này. Để tránh lỗi này hệ điều hành cần phải có cơ chế đề bảo vệ biến toàn cục dùng chung và chỉ cho phép một tiến trình duy nhất điều khiển các code truy xuất đến nó. Nếu hệ điều hành chấp nhận quy tắc: tại một thời điểm chỉ có một tiến trình được phép sử dụng thủ tục Echo và thủ tục này phải chạy cho đến khi hoàn thành mới được trao cho tiến trình khác. Thì lỗi trên sẽ không còn xuất hiện nữa. Việc sử dụng thủ tục Echo của các tiến trình P1 và P2 có thể xảy ra theo thứ tự như sau:
1. Tiến trình P1 gọi thủ tục Echo và bị dừng lại ngay sau khi hàm input được thực hiện xong. Giả sử In = A.
2. Tiến trình P2 được kích hoạt và gọi thủ tục Echo. Nhưng vì tiến trình P1 còn đang ở trong thủ tục này, cho dù đang bị treo, nên P2 phải được chuyển sang trạng thái blocked để chờ thủ tục Echo rỗi.
3. Một khoảng thời gian sau, tiến trình P1 được tái kích hoạt trở lại. P1 tiếp tục thủ tục echo cho đến khi hoàn thành. Tức là, đã hiển thị kí tự A lên màn hình.
4. Khi kết thúc P1 trả lại thủ tục echo. Khi đó P2 toàn quyền sử dụng thủ tục Echo để nhập và hiển thị kí tự lên màn hình.
Trường hợp này không xảy ra lỗi là do tiến trình P2 không tiếp tục thủ tục Echo, mặc dù đã gọi, vì nó biết P1 đã đang ở trong thủ tục Echo. Chúng ta nên lưu ý điều này, điều này sẽ được thảo luận trong mục các phương pháp điều độ tiến trình qua đoạn găng ngay sau đây.
Qua các ví dụ trên ta thấy rằng trong các hệ thống đa chương, đa người sử dụng thường xảy ra hiện tượng, nhiều tiến trình đồng thời cùng đọc/ghi dữ liệu vào một vùng nhớ, nơi chứa các biến của chương trình, và nếu không có sự can thiệp của hệ điều hành thì có thể gây hậu quả nghiêm trọng cho ứng dụng và cho cả hệ thống. Để ngăn chặn các tình huống trên hệ điều hành phải thiết lập cơ chế độc quyền truy xuất trên trên tài nguyên dùng chung. Tức là, tại mỗi thời điểm chỉ có một tiến trình duy nhất được phép truy xuất trên các tài nguyên dung chung. Nếu có nhiều tiến trình hoạt động đồng thời cùng yêu cầu truy xuất tài nguyên dùng chung thì chỉ có một tiến trình được chấp nhận truy xuất, các tiến trình khác phải xếp hàng chờ để được truy xuất sau.
Chúng ta cũng thấy rằng nguyên nhân tiềm ẩn của sự xung đột giữa các tiến
trình hoạt động đồng thời khi sử dụng tài nguyên găng là: các tiến trình này hoạt động đồng thời với nhau một cách hoàn toàn độc lập và không trao đổi thông tin với nhau nhưng sự thực thi của các tiến trình này lại ảnh hưởng đến nhau. Trường hợp lỗi trong ví dụ 3 ở trên minh chứng cho điều này.
II.2.5. Đoạn găng (Critical Section)
Đoạn code trong các tiến trình đồng thời, có tác động đến các tài nguyên có thể trở thành tài nguyên găng được gọi là đoạn găng hay miền găng. Tức là, các đoạn code trong các chương trinh dùng để truy cập đến các vùng nhớ chia sẻ, các tập tin chia sẻ được gọi là các đoạn găng.
Trong ví dụ 2 ở trên, đoạn code sau đây là đoạn găng:
{ IF (Tài khoản - Tiền rút >= 0)
Tài khoản := Tài khoản - Tiền rút }
Trong ví dụ 1 ở trên có hai đoạn găng là:
{ L1 := Count và Count := L1 }.
Để hạn chế các lỗi có thể xảy ra do sử dụng tài nguyên găng, hệ điều hành phải điều khiển các tiến trình sao cho, tại một thời điểm chỉ có một tiến trình nằm trong đoạn găng, nếu có nhiều tiến trình cùng muốn vào (thực hiện) đoạn găng thì chỉ có một tiến trình được vào, các tiến trình khác phải chờ, một tiến trình khi ra khỏi (kết thúc) đoạn găng phải báo cho hệ điều hành và/hoặc các tiến trình khác biết để các tiến trình này vào đoạn găng, vv. Các công tác điều khiển tiến trình thực hiện đoạn găng của hệ điều hành được gọi là điều độ tiến trình qua đoạn găng. Để công tác điều độ tiến trình qua đoạn găng được thành công, thì cần phải có sự phối hợp giữa vi xử lý, hệ điều hành và người lập trình. Vi xử lý đưa ra các chỉ thị, hệ điều hành cung cấp các công cụ để người lập trình xây dựng các sơ đồ điều độ hợp lý, để đảm bảo sự độc quyền trong việc sử dụng tài nguyên găng của các tiến trình.
Trong phần sau đây chúng ta sẽ tìm hiểu về các phương pháp và các sơ đồ điều độ tiến trình qua đoạn găng. Nhưng trước hết ở đây chúng ta chấp nhận một mẫu chương trình được sử dụng trong các sơ đồ điều độ tiến trình. Mẫu chương trình này mang tính chất trừu tượng, dùng để minh hoạ cho các ý tưởng điều độ. Rất ít ngôn ngữ lập trình hỗ trợ cú phát viết chương trình điều độ này. Mặc dầu đã cung cấp đầy đủ các công cụ điều độ tiến trình cho người lập trình, nhưng các hệ điều hành hiện nay đều tổ chức điều độ tiến trình ngay trong lõi (kernel) của nó nên người lập trình ít quan tâm đến tổ chức điều độ tiến trình khi lập trình. Sau đây là sơ đồ điều độ minh hoạ:
Program MultualExclution;
Const
N = ….. /*số lượng tiến trình */
{--------------------------------------------------}
Procedure P(i: integer);
Begin
Repeat
EnterCritical(R); {kiểm tra và xác lập quyền vào đoạn găng}
<Đoạn găng của P>;
ExitCritical(R); {xác lập khi rời đoạn găng}
<Đoạn không găng của>;
Until .F.
End;
{---------------------------------------------------}
BEGIN {*chương trình chính chứa các tiến trình đồng thời*} PerBegin
P(1);
P(2);
…..
P(n);
ParEnd;
END.
{---------------------------------------------------}
Sơ đồ trên tổ chức điều độ cho n tiến trình P, n tiến trình này hoạt đồng đông thời với nhau và chia sẻ tài nguyên dùng chung R. Mỗi tiến trình trong trường hợp này có một đoạn găng với tài nguyên R. Để tổ chức truy xuất độc quyền trên tài nguyên găng, mỗi tiến trình trước khi vào đoạn găng tiến trình phải gọi thủ tục EnterCritical để thiết lập quyền vào đoạn găng, để báo cho các tiến trình biết là tiến trình hiện tại đang ở trong đoạn găng. Để ra khỏi đoạn găng mỗi tiến trình phải gọi thủ tục ExitCritical, để báo cho các tiến trình khác biết là tiến trình hiện tại đã ra khỏi đoạn găng.
II.2.6. Yêu cầu của công tác điều độ qua đoạn găng
Trước hết chúng ta lưu ý lại rằng, nhiệm vụ điều độ tiến trình phải là sự phối hợp giữ phần cứng vi xử lý, hệ điều hành, ngôn ngữ lập trình và người lập trình, trong đó nhiệm vụ chính là của hệ điều hành và người lập trình. Vi xử lý, hệ điều hành và ngôn ngữ lập trình cung cấp các công cụ để hệ điều hành và/hoặc người lập trình tổ chức sơ đồ điều độ. Hệ điều hành sẽ giám sát và tổ chức thực hiện các sơ đồ điều độ này. Cho dù nhiệm vụ điều độ là của thành phần nào, thì tất cả phải đạt được các yêu cầu sau:
1. Tại một thời điểm không thể có hai tiến trình nằm trong đoạn găng.
2. Nếu có nhiều tiến trình đồng thời cùng xin được vào đoạn găng thì chỉ có một tiến trình được phép vào đoạn găng, các tiến trình khác phải xếp hàng chờ trong hàng đợi.
3. Tiến trình chờ ngoài đoạn găng không được ngăn cản các tiến trình khác vào đoạn găng.
4. Không có tiến trình nào được phép ở lâu vô hạn trong đoạn găng và không có tiến trình phải chờ lâu mới được vào đoạn găng (chờ trong hàng đợi).
5. Nếu tài nguyên găng được giải phóng thì hệ điều hành có nhiệm vụ đánh thức các tiến trình trong hàng đợi ra để tạo điều kiện cho nó vào đoạn găng.
Trước khi tìm hiểu về các giải pháp điều độ tiến trình qua đoạn găng chúng ta cần lưu ý một lần nữa rằng: nguyên lý cơ bản của điều độ là tổ chức truy xuất độc quyền trên tài nguyên găng, nhưng sự bắt buộc độc quyền này còn tồn tại hai hạn chế lớn:
1. Có thể dẫn đến tắc nghẽn (Deadlock) trong hệ thống. Chúng ta sẽ tìm hiểu về tắc nghẽn sau, bây gời chúng ta hãy xem một ví dụ về tắc nghẽn: Giả như có hai tiến trình P1 và P2, và hai tài nguyên găng R1 và R2, mỗi tiến trình đều cần truy xuất đến để mã thực hiện một hàm của nó. Và trường hợp sau đây hoàn toàn có thể xảy ra: R1 đang được giao cho P2, R2 được giao cho P1. Mỗi tiến trình đều chờ đợi được sử dụng tài nguyên thứ hai. Không một tiến trình nào giải phóng tài nguyên mà nó đang sở hữu cho đến khi có nhận được tài nguyên còn lại và thực hiện đoạn găng của nó. Cả hai tiến trình đó đều bị tắc nghẽn.
2. Các tiến trình có thể bị đói (Stravation) tài nguyên: Ví dụ sau đây cho thấy sự đói tài nguyên của các tiến trình trên hệ thống: Giả sử rằng có 3 tiến trình P1, P2, P3, mỗi tiến trình đều cần truy xuất định kỳ đến tài nguyên R. Xét trường hợp P1 đang sở hữu tài nguyên còn hai tiến trình P2, P3 phải chờ đợi tài nguyên đó. Khi mà P1 thoát khỏi đoạn găng của nó, cả P2 lẫn P3 đều có thể được chấp nhận truy xuất đến R. Giả sử rằng P3 được truy xuất R, sau đó trước khi P3 kết thúc đoạn găng của nó P1 lại một lần nữa cần truy xuất, và giả như P1 được truy xuất sau khi P3 kết thúc đoạn găng, và nếu như P1, P3 thay nhau nhận được quyền truy xuất thì P2 hầu như không thể truy cập đến tài nguyên, cho dù không có sự tắc nghẽn nào xảy ra.
I.17. Điều độ tiến trình qua đoạn găng
II.3.5. Các giải pháp phần cứng
II.3.2.a. Dùng cặp chỉ thị STI & CLI
Một số vi xử lý cung cấp cặp chỉ thị CLI và STI để người lập trình thực hiện các
thao tác mở ngắt (STI: Setting Interrupt) và cấm ngắt (CLI: Clean Interrupt) của hệ thống trong lập trình. Người lập trình có thể dùng cặp chỉ thị này để tổ chức điều độ cho các tiến trình như sau: Trước khi vào đoạn găng tiến trình thực hiện chỉ thị CLI, để yêu cầu cấm các ngắt trong hệ thống, khi đó ngắt đồng hồ không thể phát sinh, nghĩa là không có một tiến trình nào khác có thể phát sinh, nhờ đó mà tiến trình trong đoạn găng toàn quyền sử dụng tài nguyên găng cho đến hết thời gian xử lý của nó. Khi kết thúc truy xuất tài nguyên găng, tiến trình ra khỏi đoạn găng, tiến trình thực hiện chỉ thị STI để cho phép ngắt trở lại. Khi đó các tiến trình khác có thể tiếp tục hoạt động và có thể vào đoạn găng.
Trong sơ đồ điều độ này tiến trình Pi được viết như sau:
Procedure P(i: integer);
Begin
Repeat
CLI; {cấm ngắt trước khi vào đoạn găng}
<Đoạn găng của P>;
STI; {mở ngắt khi ra khỏi đoạn găng }
<Đoạn không găng>;
Until .F.
End;
{-----------------------------------------------}
Sơ đồ trên cho thấy, khi tiến trình ở trong đoạn găng nó không hề bị ngắt, do đã cấm ngắt phát sinh, nên nó được độc quyền sử dụng tài nguyên găng cho đến khi ra khỏi đoạn găng.
Sơ đồ điều độ này đơn giản, dễ cài đặt. Tuy nhiên, cần phải có sự hỗ trợ của vi xử lý và dễ gây ra hiện tượng treo toàn bộ hệ thống, khi tiến trình trong đoạn găng không có khả năng ra khỏi đoạn găng. Tiến trình không ra khỏi đoạn găng nên nó không thể thực hiện chỉ thị STI để mở ngắt cho hệ thống, nên hệ thống bị treo hoàn toàn.
Giải pháp này không thể sử dụng trên các hệ thống multiprocessor, vì CLI chỉ cấm ngắt trên vi xử lý hiện tại chứ không thể cấm ngắt của các vi xử lý khác. Tức là, sau khi đã cấm ngắt, tiến trình trong đoạn găng vẫn có thể bị tranh chấp tài nguyên găng bởi các tiến trình trên các vi xử lý khác trong hệ thống.
II.3.2.b. Dùng chỉ thị TSL (Test and set)
Trong ví dụ 2 ở trên ta đã thấy, nguyên nhân của lỗi là do hai thao tác kiểm tra tài khoản và rút tiền, bị tách rời nhau. Để tổ chức điều độ cho những trường hợp như vậy, một số vi xử lý cung cấp một chỉ thị đặc biệt cho phép kiểm tra và cập nhật nội dung một vùng nhớ trong một thao tác không thể phân chia đươc, gọi là Test and
Set lock (TSL). TSL được định nghĩa như sau :
Function TestAndSetLock(Var I:Integer):Boolean;
Begin
IF I = 0 Then
Begin
I := 1; {hai lệnh này
không}
TestAndSetLock:=True; {thể tách rời}
End
Else
TestAndSetLock := False
End;
{-------------------------------------------------}
Để tổ chức điều độ tiến trình với TSL chương trình phải sử dụng biến chia sẻ Lock, khời gán bằng 0. Theo đó, mỗi tiến trình trước khi vào đoạn găng phải kiểm tra giá trị của Lock. Nếu Lock = 0 thì vào đoạn găng. Nếu Lock = 1 thì phải đợi cho đến khi Lock = 0. Như vậy, trước khi vào đoạn găng tiến trình phải gọi hàm TestAndSetLock, để kiểm tra giá trị trả về của hàm này:
∙ Nếu bằng False, là đang có một tiến trình trong đoạn găng, thì phải chờ cho đến khi hàm trả về True, có một tiến trình vừa ra khỏi đoạn găng. ∙ Nếu bằng True, thì tiến trình sẻ vào đoạn găng để sử dụng tài nguyên găng. Khi kết thúc sử dụng tài nguyên găng ra khỏi đoạn găng thì tiến trình phải đặt lại gía trị của Lock, Lock = 0, để các tiến trình khác có thể vào đoạn găng.
Nên nhớ rằng TestAndSetLock là chỉ thị của processor, nên hệ thống đã tổ chức thực hiện độc quyền cho nó. Tức là, các thao tác mà hệ thống phải thực hiện trong chỉ thị này là không thể tách rời nhau.
Trong sơ đồ điều độ này tiến trình P được viết như sau:
Procedure P(Lock: integer);
Begin
Repeat
While (TestAndSetlock(lock)) DO;
<Đoạn găng của P>;
Lock:= 0;
<Đoạn không găng>;
Until .F.
End;
{---------------------------------------------}
Sơ đồ này đơn giản, dễ cài đặt nhưng cần phải có sự hỗ trợ của vi xử lý. Ngoài ra nó còn một hạn chế lớn là gây lãng phí thời gian xử lý của processor do tồn tại hiện tượng chờ đợi tích cực trong sơ đồ (While (TestAndSetlock(lock)) DO;). Hiện tượng chờ đợi tích cực là hiện tượng processor chỉ chờ một sự kiện nào đó xảy ra mà không làm gì cả.
⮚ Tóm lại: Việc sử dụng các chỉ thị phần cứng đặc biệt để tổ chức điều độ tiến trình qua đoạn găng, hay còn gọi là tổ chức truy xuất độc quyền trên tài nguyên găng, có những thuận lợi và bất lợi sau đây:
Thuận lợi:
∙ Nó thích hợp với một số lượng bất kỳ các tiến trình cả trên hệ hệ thống Uniprocessor và hệ thống Multiprocessor.
∙ Nó khá đơn giản cho nên dễ xác định độ chính xác.
∙ Nó có thể được sử dụng để hỗ trợ cho nhiều đoạn găng; mỗi đoạn găng có thể định nghĩa cho nó một biến riêng.
Bất lợi:
∙ Trong khi một tiến trình đang chờ đợi được vào đoạn găng thì nó tiếp tục làm tốn thời gian xử lý của processor, mà ta gọi là chờ đợi tích cực. ∙ Sự đói tài nguyên có thể xảy ra. Khi một tiến trình rời khỏi một đoạn găng, bộ phận điều độ tiến trình phải chọn một tiến trình trong số nhiều tiến trình ngoài đoạn găng để cho nó vào đoạn găng. Việc chọn này có thể dẫn đến hiện tượng có một tiến trình đợi mãi mà không thể vào đoạn găng được. ∙ Sự tắc nghẽn có thể xảy ra. Hãy xét một tình huống trên một hệ thống
uniprocessor. Tiến trình P1 thực thi chỉ thị đặc biệt (TesAndSetLock, Exchange) và vào đoạn găng của nó. P1 sau đó bị ngắt để nhường processor cho P2, P2 là tiến trình có độ ưu tiên cao hơn. Nếu như P2 cũng định sử dụng tài nguyên như P1, P2 sẽ bị từ chối truy xuất bởi vì cơ chế độc quyền. Do đó P2 sẽ đi vào vòng lặp busy
waitting. Tuy nhiên, P1 sẽ không bao giờ được cấp processor để tiếp tục vì nó có độ ưu tiên thấp hơn so với P2.
II.3.6. Các giải pháp dùng biến khoá
II.3.3.a. Dùng biến khoá chung
Xuất phát từ nguyên tắc cơ bản của tổ chức độc quyền là, tại mỗi thời điểm chỉ có duy nhất một tiến trình có thể truy xuất đến một vùng nhớ chia sẻ, các hệ điều hành sử dụng biến khoá chung để tổ chức truy xuất độc quyền trên tài nguyên găng. Phương pháp này còn gọi là phương pháp Busy and Waitting (bận và đợi), nó được nhà toán học người Hà Lan tên là Dekker đề xuất.
Với mỗi tài nguyên găng, hệ điều hành dùng một biến chung để điều khiển việc sử dụng tài nguyên này của các tiến trình đồng thời. Tạm gọi là biến chung này là Lock, Lock được chia sẻ cho nhiều tiến trình và được khởi gán = 0.
Theo đó, mỗi tiến trình trước khi vào đoạn găng phải kiểm tra giá trị của Lock:
∙ Nếu Lock = 1, tức là đã có tiến trình nào đó trong đoạn găng, thì tiến trình phải chờ cho đến khi Lock = 0 (có thể chuyển sang trạng thái blocked để chờ).
∙ Nếu Lock = 0, tức là không có tiến trình nào trong đoạn găng, thì tiến trình thiết lập quyền vào đoạn găng, đặt Lock = 1, và vào đoạn găng. Tiến trình vừa ra khỏi đoạn găng phải đặt Lock = 0, để các tiến trình khác có thể vào đoạn găng.
Trong sơ đồ điều độ này tiến trình P được viết như sau:
Procedure P(Lock: integer);
Begin
Repeat
While Lock = 1 DO ; {đợi cho đến khi Lock = 0}
Lock :=1; {thiết lập quyền vào đoạn găng}
<Đoạn găng của P>; {vào đoạn găng}
Lock:= 0; {thông báo là đã rời đoạn găng }
<Đoạn không găng>;
Until .F.
End;
{------------------------------------------------}
Sơ đồ điều độ dùng biến khoá chung này đơn giản, dễ xây dựng nhưng vẫn xuất hiện hiện tượng chờ đợi tích cực, khi chờ cho đến khi Lock = 0 (While Lock = 1 DO;). Hiện tương chờ đợi tích cực gây lãng phí thời gian của processor.
Nếu một tiến trình trong đoạn găng không thể ra khỏi đoạn găng, thì các tiến trình chờ ngoài đoạn găng có thể chờ đợi vô hạn (vì Lock không được đặt lại = 0).
II.3.3.b. Dùng biến khoá riêng
Để khắc phục hạn chế của phương pháp dùng biến chung, các hệ điều hành có thể dùng giải pháp biến riêng để tổ chức điều độ tiến trình. Mỗi tiến trình sử dụng một biến khoá Lock riêng, tương ứng với một tài nguyên găng trong hệ thống. Biến khoá riêng của tất cả các tiến trình đều được khởi gán bằng 0, tức là chưa vào đoạn găng
Theo đó, mỗi tiến trình trước khi vào đoạn găng ứng với một tài nguyên găng nào đó thì trước hết phải kiểm tra biến khoá riêng, tương ứng với tài nguyên găng mà tiến trình muốn truy xuất, của tất cả các tiến trình còn lại: ∙ Nếu tồn tại một biến khoá riêng của một tiến trình nào đó bằng 1, Lock
= 1, tức là đã có một tiến trình nào đó ở trong đoạn găng, thì tiến trình phải chờ ngoài đoạn găng cho đến khi tất cả biến khoá riêng = 0.
∙ Nếu tất cả các biến khóa riêng của các tiến trình đều = 0, Lock = 0, tức là không có tiến trình nào trong đoạn găng, thì tiến trình thiết lập quyền vào đoạn găng, đặt Lock = 1, và vào đoạn găng. Tiến trình vừa ra khỏi đoạn găng phải đặt Lock = 0, để các tiến trình khác có thể vào đoạn găng.
Sau đây là sơ đồ điều độ dùng biến khoá riêng cho hai tiến trình đồng thời P1 và P2. Hai tiến trình này dùng hai biến khoá riêng là Lock1 và Lock2: Program MultualExclution;
Const N:2;
Var
Lock1, Lock2: byte;
BEGIN
Lock1 = 0; Lock2 = 0;
ParBegin
P1: Repeat {tiến trình P1}
While Lock2 = 1 Do ; {P2 đang ở trong đoạn găng }
Lock1 := 1; {P1 thiết lập quyền vào đoạn găng}
<Đoạn găng của P1>;
Lock1 := 0; {P1 ra khỏi đoạn găng}
<Đoạn không găng của P1>;
Until .F.
P2: Repeat {tiến trình P2}
While Lock1 = 1 Do; {P1 đang ở trong đoạn găng }
Lock2 := 1; {P2 thiết lập quyền vào đoạn găng}
<Đoạn găng của P2>;
Lock2 := 0; {P2 ra khỏi đoạn găng}
<Đoạn không găng của P2>;
Until .F.
ParEnd
END.
{--------------------------------------------------------}
Sơ đồ này đơn giản dễ cài đặt. Một tiến trình nào đó ở ngoài đoạn găng bị blocked sẽ không ngăn cản được các tiến trình khác vào đoạn găng, nhưng nếu tiến trình trong đoạn găng bị lỗi không thể ra khỏi đoạn găng , Lock luôn luôn = 0, thì
các tiến trình khác sẽ không được quyền vào đoạn găng.
Phương pháp này vẫn còn tồn tại hiện tượng chờ đợi tích cực và sơ đồ điều độ sẽ trở nên phức tạp khi có nhiều hơn hai tiến trình muốn vào đoạn găng. Sơ đồ này có thể xảy ra một lỗi nghiêm trọng đó là: Có thể có hai tiến trình cùng nằm trong đoạn găng. Nguyên nhân của lỗi này là do việc kiểm tra quyền vào đoạn găng và và việc xác lập quyền vào đoạn găng của tiến trình bị tách rời khi thực hiện. Tức là, P1 và P2 có thể bị điều phối thực hiện theo thứ tự sau: 1. P1 được cấp processor: P1 thực thi vòng lặp While và tìm xem thử Lock2 = 1 không. Khi P1 vừa nhìn thấy Lock2 = 0, thì bị thu hồi processor.
2. P2 được cấp processor: P2 thực thi vòng lặp While và tìm xem thử Lock1 = 1 không. Khi P2 vừa nhìn thấy Lock1 = 0, thì bị thu hồi processor.
3. P1 được cấp processor trở lại: P1 không kiểm tra lại Lock2 mà chỉ đặt Lock1 = 1 và vào đoạn găng của nó. Khi vừa vào đoạn găng thì bị thu hồi processor.
4. P2 được cấp processor trở lại: P2 không kiểm tra lại Lock1 mà chỉ đặt Lock2 = 1 và vào đoạn găng của nó.
Rõ ràng với thực tế này thì cả P1 và P2 đều nằm trong đoạn găng. Và chúng ta đã biết điều gì sẽ xảy ra khi hai tiến trình đồng thời truy xuất tài nguyên găng trong các ví dụ về tài nguyên găng ở trên.
Nhiều nhà thiết kế hệ điều hành đã cải tiến sơ đồ điều độ ở trên để khắc phục hạn chế trên đây và một số hạn chế khác của nó.
II.3.7. Các giải pháp được hỗ trợ bởi hệ điều hành và ngôn ngữ lập trình Các giải pháp trên tồn tại hiện tượng chờ đợi tích cực, gây lãng phí thời gian xử lý của processor. Điều này có thể khắc phục bằng một nguyên tắc rất cơ bản: nếu một tiến trình khi chưa đủ điều kiện vào đoạn găng thì được chuyển ngay sang trang thái blocked để nó trả lại processor cho hệ thống, để hệ thống cấp cho tiến trình khác. Để thực hiện được điều này cần phải có sự hỗ trợ của hệ điều hành và các ngôn ngữ lập trình để các tiến trình có thể chuyển trạng thái của nó. Hai thủ tục Sleep và Wakeup được hệ điều hành cung cấp để sử dụng cho mục đích này:
∙ Khi tiến trình chưa đủ điều kiện vào đoạn găng nó sẽ thực hiện một lời gọi hệ thống để gọi Sleep để chuyển nó sang trạng thái blocked, và tiến trình được gọi này đưa vào hàng đợi để đợi cho đến khi có một tiến trình khác gọi thủ tục Wakeup để giải phóng nó ra khỏi hàng đợi và có thể đưa nó vào đoạn găng.
∙ Một tiến trình khi ra khỏi đoạn găng phải gọi Wakeup để đánh thức một tiến trình trong hang đợi blocked ra để tạo điều khiện cho tiến trình này vào đoạn găng.
Như vậy giải pháp này được áp dụng trên nhóm các tiến trình hoạt động đồng thời có trao đổi thông tin với nhau, và các tiến trình phải hợp thác với nhau để hoàn thành nhiệm vụ. Các tiến trình này liên lạc với nhau bằng cách gởi tín hiệu cho nhau. Một tiến trình trong hệ thống này có thể bị buộc phải dừng (bị blocked) cho đến khi nhận được một tín hiệu nào đó từ tiến trình bên kia, đó là tiến trình hợp tác với nó.
Thực tế đã chỉ ra được rằng, nếu chỉ dùng hai thủ tục trên thì sơ đồ điều độ sẽ không đáp ứng được các yêu cầu của công tác điều độ, do đó khi cài đặt các hệ điều hành chỉ sử dụng ý tưởng của Sleep và Wakeup. Sau đây là các giải pháp sử dụng ý tưởng của Sleep và Wakeup.
II.3.3.a. Giải pháp dùng Semaphore (sự đánh tín hiệu bằng cờ) (đèn báo) Giải pháp này được Dijkstra đề xuất vào năm 1965. Semaphore (sự đánh tín hiệu bằng cờ) được định nghĩa để sử dụng trong các sơ đồ điều độ như sau:
∙ Semaphore (sự đánh tín hiệu bằng cờ) S là một biến nguyên, khởi gán bằng một giá trị không âm, đó là khả năng phục vụ của tài nguyên găng tương ứng với nó.
∙ Ứng với S có một hàng đợi F(s) để lưu các tiến trình đang bị blocked trên S.
∙ Chỉ có hai thao tác Down và Up được tác động đến semaphore (sự đánh tín hiệu bằng cờ) S. Down giảm S xuống một đơn vị, Up tăng S lên một đơn vị.
∙ Mỗi tiến trình trước khi vào đoạn găng thì phải gọi Down để kiểm tra và xác lập quyền vào đoạn găng. Khi tiến trình gọi Down(S) thì hệ thống sẽ thực hiện như sau: S := S -1, nếu S > = 0 thì tiến trình tiếp tục xử lý và vào đoạn găng, nếu S < 0 thì tiến trình phải vào hàng đợi để chờ cho đến khi S > = 0. Down được cài đặt như sau:
Procedure Down(s);
Begin
S := S -1;
If S < 0 Then {S >= 0 thì tiếp tục}
Begin
Status(p)= blocked; {chuyển tiến trình sang
blocked}
Enter(p, F(s)); {đưa tiến trình vào hàng đợi F(S)}
end;
End;
∙ Mỗi tiến trình ngay sau khi ra khỏi đoạn găng phải gọi Up để kiểm tra