24/05/2018, 19:38

Khái niệm quá trình và luồng

Trong HĐH phân tán, hai phần tử thiết yếu là QT và luồng (thread). Quản lý QT được phân lớp triển khai theo ba khu vực (cũng là ba chức năng liên quan đến quản lý QT trong hệ phân tán): + Truyền thông QT, + Đồng bộ hoá QT, + Lập lịch QT. ...

Trong HĐH phân tán, hai phần tử thiết yếu là QT và luồng (thread). Quản lý QT được phân lớp triển khai theo ba khu vực (cũng là ba chức năng liên quan đến quản lý QT trong hệ phân tán):

+ Truyền thông QT,

+ Đồng bộ hoá QT,

+ Lập lịch QT.

Ba chức năng này thuộc vào một thể thống nhất và không tách rời nhau.

Các chức năng truyền thông và đồng bộ có mối quan hệ mật thiết cả về khái niệm và lẫn khi thi hành. Các khái niệm và việc thi hành phối hợp được trình bày trong hai chương III và IV.

Lập lịch QT liên quan đến trình tự thực hiện các QT để đạt được hiệu suất tốt nhất cho hệ thống. Trình tự thực hiện QT tuỳ thuộc vào đồng bộ QT trong khi hiệu suất lại phụ thuộc vào năng lực lớn mạnh của kĩ thuật truyền tin cơ sở và thời gian trễ trong quá trình truyền tin. Do đặc thù khá riêng biệt nên lập lịch QT được trình bày trong chương V. Dù cho truyền thông QT, đồng bộ QT và lập lịch QT có những đặc điểm chung như trong HĐH tập trung, song nhằm mục đích định hướng hệ phân tán cho nên trình bày quản lí QT có trong ba chương III, IV và V .

Trước hết bắt đầu với các định nghĩa và các đặc điểm của điều khiển QT.

QT là đối tượng trong HĐH, biểu thị việc thực hiện một chương trình trong một phiên làm việc: QT là một đơn vị tính toán cơ sở trong hệ thống.

Một số điểm phân biệt hai khái niệm chương trình và QT: Chương trình liên quan đến bài toán cần giải quyết (các tham số hình thức), tên chương trình, độ dài, ngôn ngữ nguồn .… QT là một lần sử dụng chương trình đã có để giải quyết bài toán trong một tình huống cụ thể (tham số đã được cụ thể). QT có trạng thái quá trình, bao gồm trạng thái phân bố các thành phần của QT trong bộ nhớ trong ...

QT được gọi là đơn nếu các lệnh (thành phần con) trong nó được thực hiện một cách tuần tự. Thuật ngữ đồng thời liên quan đến việc mô tả sự thực hiện đồng thời các QT đơn. Giữa hai QT có những thành phần được phép thực hiện đồng thời. Các thành phần khác cần được đồng bộ hoặc truyền thông giữa chúng.

Luồng (thread) là một biến thể của QT, tương ứng với trường hợp khi thực hiện một QT lại sinh ra một QT khác. QT đơn thực chất là QT đơn luồng, trong thời gian thực hiện, nó không tạo ra một QT mới.

QT đa luồng là QT mà trong khi thực hiện nó cho ra một QT mới: Đây là trường hợp đặc biệt của tính đồng thời khi QT cha và QT con "đồng thời" thực hiện và chia xẻ tài nguyên CPU cùng bộ nhớ trong và mỗi luồng có trạng thái riêng của mình.

Hình 3.3 trình bày tính đồng thời hai mức của một QT và một luồng. Tại mức thứ nhất (mức thấp), các QT chạy đồng thời dị bộ theo HĐH gốc. Khi xem xét tại mức đồng thời thứ hai, mỗi QT đồng thời chạy tựa một máy tính ảo hỗ trợ tính đồng thời của các luồng. Một QT được hiểu một cách đơn giản như một không gian địa chỉ lôgic mà tại đó luồng thực hiện.

Trong HĐH tập trung, thuật ngữ "khối điều khiển QT" PCB (Process Control Block) dùng để chỉ cấu trúc dữ liệu chứa các thông tin về QT, hỗ trợ việc điều khiển CPU và điều khiển QT (thông tin trạng thái: thanh ghi địa chỉ lệnh, nội dung các thanh ghi, con trỏ stack, cổng truyền thông, và đặc tả file ...). PCB chứa các thông tin cần thiết để luân chuyển thực hiện QT được quản lý bằng HĐH gốc.

Giống như QT, luồng cũng có các thủ tục và stack riêng. Thông tin trạng thái về luồng được cho trong khối điều khiển luồng TCB (Thread Control Block). TCB được quản lý bởi Thư viện hỗ trợ thời gian chạy luồng. TCB là riêng đối với mỗi luồng trong khi PCB lại được chia xẻ cho các luồng tương tác để đồng bộ và truyền thông. Thông tin trong TCB ít hơn nhiều so với thông tin trong PCB và chỉ gồm nội dung các thanh ghi (bộ đếm chương trình, đỉnh stack, tập thanh ghi). Các thông tin trạng thái khác được bảo quản trong PCB. Bởi lý do đó, luồng được gọi QT nhẹ trong khi đó QT được gọi là QT nặng. Chú ý về mặt sử dụng ký hiệu, trong các HĐH hoạt động theo chế độ mẻ (batch, lô) dùng ký hiệu TCB với nghĩa khác là "khối điều khiển bài toán" - Task Control Block.

Thi hành luồng trong không gian người dùng được chỉ ra trong hình 3.4, và chỉ có QT (mà không phải là luồng) được HĐH nhìn thấy. Ngoài ra, luồng được thực hiện trong không gian nhân và được quản lý trực tiếp bởi HĐH gốc. Luồng trong một QT được khởi tạo tĩnh hoặc động bởi một QT điều khiển hoặc một luồng khác.

Các ứng dụng luồng

Luồng có nhiều ứng dụng trong HĐH phân tán. Chúng thường được dùng khi thi hành một QT phục vụ cung cấp các dịch vụ tương tự hoặc có quan hệ tới các QT đa khách, chẳng hạn như phục vụ trạm cuối hoặc phục vụ file.

Khi một yêu cầu phục vụ (serving request) từ QT khách tới một QT phục vụ đơn luồng, thì QT phục vụ này tự tạm ngừng (có thể quan niệm phục vụ này như một tài nguyên được điều khiển bởi một semaphore nhị phân) để chờ đợi hoàn thiện các điều kiện hoặc thao tác nào đó từ trước. Tuy nhiên, việc tạm ngưng phục vụ lại kết khối các yêu cầu khách mới được đưa tới phục vụ. Để tăng thông lượng hệ thống, đa bản sao của cùng một phục vụ được khởi tạo cho các yêu cầu khác nhau tới cùng một phục vụ một cách đồng thời. Do các luồng phục vụ này có mã lệnh tương tự nhau và bắt buộc phải tương tác nhau qua thông tin toàn cục được chia xẻ, vì vậy chúng được nhóm trong một không gian điạ chỉ, và như vậy là đã khởi tạo tính đa luồng trong một phục vụ đơn.

QT khách cũng được điều khiển theo cách hoàn toàn tương tự. Một QT khách yêu cầu tạo ra nhu cầu đồng thời tới các phục vụ và bỏ qua việc bị kết khối bởi bất kỳ từ các yêu cầu dịch vụ này.

Hình 3.4 mô tả ba ứng dụng luồng trong hệ phân tán.

-Phục vụ trạm cuối (phức hợp và tập trung dữ liệu) trong hình 3.4a:

Chức năng tập hợp dữ liệu đa thành phần từ nhiều trạm cuối vào bộ đệm chung và gửi dữ liệu phức trong một bộ đệm chung tới một máy tính (hay mạng). Nếu không dùng đa luồng, phục vụ trạm cuối cần bầu cử trạm cuối đưa vào bằng cách sử dụng dịch vụ nguyên thuỷ không kết khối. Theo quan niệm, sẽ đơn giản hơn nếu thiết kế phục vụ thành đa luồng, mỗi từ chúng đáp ứng một input riêng. Mã lệnh của các luồng này là đồng nhất nên được chia xẻ như mã thực hiện lại mà mỗi luồng có stack cục bộ riêng của mình. Việc truy nhập vào buffer cùng được chia xẻ bởi các luồng cần loại trừ ràng buộc. Việc loại trừ ràng buộc có thể đạt được bằng cách sử dụng phương pháp đồng bộ bộ nhớ chia xẻ như semaphore hay bộ kiểm tra, vì tất cả các luồng chia xẻ một vùng địa chỉ. Hơn nữa đồng bộ luồng có thể hiệu quả hơn nhiều vì QT đồng bộ chỉ gọi phần cục bộ và có thể tránh được việc gọi nhân trong một số trường hợp. Các luồng trong ví dụ phục vụ trạm cuối này được tạo tĩnh và chạy không tiền định. Về cơ bản, chúng chạy giống như một bộ điều khiển ngắt thật sự.

-Hình 3.4b, trình bày một tình huống ứng dụng luồng khác. Phục vụ File thi hành các thao tác dịch vụ file khác nhau theo yêu cầu từ khách. Một luồng được tạo ra cho mỗi thao tác và điều khiển được quay lại luồng chính, và như vậy luồng chính có thể tiếp nhận một yêu cầu mới. Trong những điều kiện nào đó, luồng được kết khối, và một luồng khác được lập lịch để thực hiện. Luồng ngừng tồn tại khi công việc của nó hoàn thành. Kết khối luồng và lập lịch luồng được trình bày ở phần sau. Chú ý là trong ví dụ về phục vụ file, tồn tại luồng chính phục vụ như một trình điều phối công việc cho các dịch vụ file đồng thời; việc khởi tạo và kết thúc luồng là động. Tạo luồng và huỷ luồng là đơn giản vì lí do dùng lại không gian nhớ. Đây là cấu trúc luồng phổ biến cho phần lớn các loại phục vụ này.

 Ví dụ thứ 3 về luồng cho trong hình 3.4(c) là một khách đưa ra nhiều yêu cầu tới các phục vụ khác nhau. Đa luồng trong QT khách làm cho nó có thể đạt được đồng thời các dịch vụ và dị bộ thậm chí khi thông tin yêu cầu trả lời là đồng bộ. Một ứng dụng hữu dụng của cấu trúc này là việc cập nhật đồng thời các bản sao file nhân bản mà được quản lí bởi nhiều phục vụ file.

Hỗ trợ luồng trong nhiều HĐH hiện đại rất rộng lớn bởi vậy người lập trình ứng dụng có thể viết các chương trình đồng thời một cách hiệu quả. Ví dụ, ứng dụng duyệt web đa luồng có thể khởi tạo việc truyền fie đa thành phần, cho phép làm chậm QT truyền file ở Internet chồng lên nhau.

-Một ví dụ ứng dụng đa luồng khác là hệ thống đa cửa sổ. Các ứng dụng toạ độ cửa sổ trở nên dễ dàng hơn nếu chúng được thực hiện ở trong luồng với chia xẻ vùng địa chỉ logic chia xẻ. Chẳng hạn, một luồng có thể thực hiện một hoạt động trong cửa sổ này mà kết quả lại để trong một cửa sổ khác. Để thực hiện hiệu quả những ứng dụng này, các luồng ưu tiên và các hỗ trợ bộ đa xử lí được đòi hỏi.

Thi hành luồng trong không gian người dùng

Hỗ trợ luồng như một gói thêm vào đã được thực hiện trên nhiều hệ thống bao gồm gói luồng DCE từ Tổ chức phần mềm mã mở OSF và gói QT nhẹ (LWP: Light Weight Process) từ Sun. Vấn đề thi hành cốt lõi là nắm giữ được các lời gọi hệ thống đang kết khối từ một luồng và lập lịch luồng để thực hiện trong một QT. Trong thi hành luồng trong không gian người dùng (chương trình người dùng), một QT được ấn định chia xẻ thời gian bộ xử lí như thường được làm trong bất cứ HĐH nào. Khoảng thời gian được ấn định này là đa thành phần giữa các luồng đang tồn tại. Các luồng chạy dựa trên thư viện hỗ trợ thời gian chạy luồng. Trách nhiệm của một thủ tục thời gian chạy luồng là thực hiện việc chuyển ngữ cảnh từ luồng này sang luồng khác. Mỗi lời gọi hệ thống kết khối từ một luồng đang thực hiện là không bị HĐH bẫy lỗi nhưng được gửi tới một thủ tục thời gian chạy. Thủ tục thời gian chạy sẽ đơn giản khi giữ lại TCB của luồng gọi và tải (nạp) TCB của luồng mà nó lựa chọn tạo thành các thanh ghi phần cứng (bộ đếm chương trình, các thanh ghi và các con trỏ stack) với giả thiết rằng nó được phép thực hiện như các thao tác đặc cách. Và kết quả, không một kết khối thực sự trong hệ thống xuất hiện nhưng một luồng bị kết khối trong hàng đợi được duy trì bằng thư viện hỗ trợ thời gian chạy, và sự thực hiện QT lại được tiếp tục với một luồng khác.

Việc chuyển ngữ cảnh luồng yêu cầu một tải rất nhỏ vì nó bao hàm việc lưu giữ và khôi phục chỉ bộ đếm chương trình, các con trỏ stack. Hơn nữa, việc lập lịch chạy luồng được thực hiện bằng Thư viện thời gian chạy, người dùng có quyền lựa chọn mức ưu tiên tới luồng được tạo. Lập lịch cho luồng thông thường là theo không ưu tiên và dựa theo quyền ưu tiên vào trước thì phục vụ trước (FCFS - First Come First Served); Nó có thể là lập lịch có ưu tiên theo các mức khác nhau khi luồng mới được tạo có mức ưu tiên cao hơn. Sơ đồ có ưu tiên, chẳng hạn việc thực hiện cuộn (RR: Round Robin) các luồng sẽ khó hơn khi không sử dụng ngắt đồng hồ và thật sự là không cần thiết ở mỗi mức luồng. Nếu cần, một luồng có thể bao gồm nguyên thuỷ luồng ngủ hoặc nhường cho phép từ bỏ sự thực hiện của một luồng tới luồng khác nhằm tạo ra tính không đồng bộ chạy luồng. Các nguyên thủy luồng có trong các gói luồng điển hình là:

-Quản lí luồng để thực hiện việc tạo luồng, tạm dừng, kết thúc luồng.

-ấn định ưu tiên và các thuộc tính luồng khác.

-Hỗ trợ đồng bộ và truyền thông chẳng hạn như semaphore, monitor, và CTĐ.

Thi hành luồng trong không gian nhân của hệ điều hành

Các gói luồng được thi hành như một mức phần mềm trong không gian người dùng là dễ thực hiện và cơ động mà không đòi hỏi phải thay đổi nhân. Luồng có thể được thi hành ở mức nhân với một số mở rộng. Khi thi hành luồng trong không gian nhân, việc kết khối và lập lịch luồng được xử lí như thông thường nhưng lại mềm dẻo hơn và hiệu quả hơn. Ví dụ, luồng có thể được ưu tiên một cách dễ dàng, một luồng phát ra một lời gọi hệ thống thì nó có thể bị kết khối mà không kết khối các luồng khác thuộc cùng QT và mỗi luồng có thể hoàn thành một chu trình của bộ xử lí với cùng cơ sở của các QT. Tuy nhiên, sự trừu tượng hai mức tinh vi đối với đồng thời trở nên mờ nhạt hơn và lợi thế tải chuyển ngữ cảnh luồng của QT nhẹ không còn nữa. Tính cơ động và hai mức trừu tượng đồng thời đôi khi nảy sinh thêm bất lợi khác.

Giống như các khái niệm mô hình Client/Server và RPC, luồng là khái niệm thiết kế hệ thống cơ bản. Việc lựa chọn thi hành luồng trong không gian nhân hay trong không gian người dùng là một nhân tố thiết kế hệ thống khó tính. Cách kết hợp thi hành luồng cả không gian người dùng và không gian nhân như trong Sun’s Solaris hội tụ được các lợi điểm của hai hướng tiếp cận trên. Phần dưới đây minh họa việc kết hợp hỗ trợ nhân đa luồng như vậy.

Nhân truyền thống là những luồng đơn. Thường thì chỉ có một bộ xử lí và cấu trúc của nhận là rất gọn. Vì vậy, đòi hỏi dịch vụ nhân chạy trong một luồng đơn không cần tính sự ưu tiên. Không đồng bộ là điều cần thiết trong thao tác nhân. Gần đây, hai khuynh hướng quan trọng đã được nảy sinh cho những hệ thống hiện đại. Thứ nhất, máy tính đơn với nhiều bộ xử lý đã trở nên thông dụng. Thứ hai là sự phức tạp về nhu cầu phần mềm đòi hỏi phải tạo ra nhiều dịch vụ mới trong nhân. Nhân đa luồng hỗ trợ cho những dịch vụ nhân đồng thời đã được khẳng định.

Thao tác nội tại của nhân và những dịch vụ mà nhân cung cấp tới ứng dụng của người dùng có thể được thi hành như luồng. Luồng trong không gian nhân đã được phức hợp trong một hệ đa bộ xử lý hạ tầng. Việc thực hiện luồng là song song thực sự và có thể định ưu tiên. Sự đồng bộ giữa những luồng trong nhân trở nên cần thiết và có thể thực hiện được bằng cách dùng bộ nhớ chia xẻ. Để kết hợp chặt chẽ luồng trong không gian người dùng và luồng trong không gian nhân trong cùng một hệ thống, Solaris giới thiệu một khái niệm luồng mức trung gian và gọi là QT nhẹ LWP. LWP được QT người sử dụng tạo ra và được chương trình con (trong thư viện) thời gian chạy luồng quản lý. Chúng được nhân tổ chức như là đơn vị cơ sở cho việc lập lịch. Luồng người dùng, không thể được nhân nhận biết, cũng được tạo ra và quản lý bởi bó luồng. LWP phục vụ giao diện luồng người dùng và luồng nhân. Hình 3.5 thể hiện nhân đa luồng có ưu tiên với ba mức đồng thời: Luồng của người sử dụng là đa thành phần theo LWP trong cùng một QT; LWP là đa thành phần theo luồng nhân và luồng nhân là đa thành phần trong hệ đa bộ xử lý.

Luồng người dùng có thể được lập lịch tới bất cứ một LWP nào được QT tạo ra. Khi được gắn tới một LWP, nó trở thành thực hiện được khi dùng thời gian được nhân đã định vị tới LWP. Mỗi LWP lại được kết nối tới một luồng nhân. Lời gọi kết khối từ một luồng người sử dụng sẽ bẫy tới một LWP. LWP đó tạo ra một hệ thống thực gọi đến nhân và trở thành kết khối. Việc kết khối LWP không làm kết khối toàn bộ QT do các luồng đợi có thể được lập lịch tới LWP khác trong cùng QT. Luồng người dùng có thể được ưu tiên vì rằng các LWP có thể được ưu tiên bởi nhân. Việc thi hành lai có tính mềm dẻo và hiệu quả từ cả luồng người dùng và luồng nhân.

Rất nhiều HĐH hiện thời có hỗ trợ luồng và có một số lượng lớn các phần mềm sử dụng luồng. Sự hỗ trợ luồng trở thành một bộ phận trong HĐH ngày nay.

0