Cấu trúc kiểu kênh thông điệp và tiến trình

Một phần của tài liệu (LUẬN văn THẠC sĩ) kết hợp phương pháp kiểm chứng mô hình và các kỹ thuật kiểm thử phần mềm làm tăng độ tin cậy của hệ thống phần mềm (Trang 40 - 43)

Chương 4 Ngôn ngữ Promela và công cụ kiểm chứng mô hình SPIN

4.1. Ngôn ngữ Promela

4.1.3. Cấu trúc kiểu kênh thông điệp và tiến trình

a. Dữ liệu kiểu kênh trong Promela

Một kênh trong Promela là một kiểu dữ liệu với hai toán tử: sendreceive. Mỗi kênh kết hợp với một kiểu thông điệp (message type); một kênh sẽ phải được khởi tạo. Nó chỉ có thể gửi và nhận các thông điệp của loại thông điệp của nó. Có thể tạo được 255 kênh. Một kênh được khai báo với một khởi tạo đặc tả dung lượng kênh (channel capacity) và kiểu thông điệp:

chan ch = [capacity] of {typename, …, typename}

Dung lượng kênh phải là một hằng số nguyên không âm. Kiểu thông điệp đặc tả cấu trúc của mỗi thông điệp có thể được gửi trẻn kênh cũng như là một chuỗi của các trường; số trường; và kiểu của mỗi trường được đặc tả trong khai báo. Kiểu của một thông điệp không thể là kiểu mảng, tuy nhiên, thông điệp có thể có kiểu tự định nghĩa

typedefmà kiểu typedef có thể chứa một mảng trong đó.

Có hai loại kênh với ngữ nghĩa khác nhau: các kênh gặp (rendezvous channels) với dung lượng bằng không và các kênh đệm (buffered channels) với dung lượng lớn hơn không.

Hình 4.2 là đoạn mã Promela mô tả việc sử dụng kênh để gửi nhận dữ liệu trên hệ thống Client – Server. Trong chương trình ở hình 4.2 thì lệnh gửi (send statement) của Client0 có cấu trúc là request!0 trong đó request là tên kênh, dấu ! báo hiệu đây là kênh gửi, 0 là message gửi với đối số là 0. Lệnh nhận (receive statement) của Server có cấu trúc request?client nhận các yêu cầu từ client, dáu ? báo hiệu đây là kênh nhận.

b. Kênh gặp (Rendezvous channels)

Một kênh được khai báo với dung lượng bằng không thì được gọi là một kênh gặp. Có nghĩa là việc chuyển thông điệp từ một sender (một tiến trình với một lênh gửi) tới receiver (một tiến trình với một lệnh nhận) là đồng bộ và được thực thi như một toán tử nguyên tử đơn.

Hình 4.3 là ví dụ về hoạt động của kênh gặp:

Hình 4.3. Ví dụ về kênh gặp

Ở dòng 5 hình 4.3, khi mà bên gửi gửi một thông điệp trên kênh gặp thì ở dòng 13, bên nhận có lệnh nhận tương ứng, thì kênh gặp có thể được chấp nhận (accept) và giá trị của dữ liệu trong lệnh gửi được sao chép vào các biến trong lệnh nhận. Trạng thái của chương trình sẽ thay đổi. Hình 4.4 mô tả sơ đồ gửi nhận thông điệp trên kênh gặp.

Hình 4.4. Sơ đồ gửi nhận thông điệp trên kênh gặp

Kênh gặp là một phép toán nguyên tử, thậm chí nếu có những tiến trình khác, không có thời gian đệm vào giữa quá trình thực thi của các câu lệnh gửi và lệnh nhận.

Kênh gặp có nhược điểm là dễ gây ra nhầm lẫn khi có nhiều kênh gửi nhận cùng lúc. Giải pháp để tránh nhầm lẫn là sử dụng mảng kênh gặp để có thể đưa ra tương ứng giữa kênh gửi và kênh nhận, để hai bên gửi – nhận đến được đúng kênh.

Nhược điểm của kênh gặp: Thông thường ta sẽ có nhiều máy khách (clients) hơn là máy chủ (servers). Nếu sử dụng kênh gặp trong truyền thông điệp, thì số máy khách được phục vụ sẽ không lớn hơn số máy chủ (vì ở đây là sử dụng cơ chế đồng bộ), và những máy khách còn lại sẽ bị khóa (blocked).

c. Kênh đệm (buffered channels)

Kênh đệm là giải pháp cho nhược điểm có thể gặp phải khi sử dụng kênh gặp. Kênh đệm sắp xếp các yêu cầu được gửi bởi máy khách theo cách mà chúng không bị khóa ở trên cả máy khách và máy chủ.

Một kênh được khai báo với một dung lượng lớn hơn không được gọi là một kênh đệm:

chan ch = [3] of {mtype, byte, bool};

Dung lượng là số thông điệp của kiểu thông điệp có thể lưu được trong kênh.

Hình 4.5. Sơ đồ gửi nhận thông điệp trong kênh đệm

Các câu lệnh gửi và nhận của kênh được đặt trong hàng đợi FIFO. Sơ đồ trên hình 4.5 chỉ ra rằng kênh đã xuất hiện với hai thông điệp đã sẵn sàng để gửi tới kênh. Câu lệnh gửi được thực hiện vì có một chỗ trong kênh cho các thông điệp, kênh không bị đầy (not full); và thực thi câu lệnh được đặt trong thông điệp ở cuối hàng đợi. Câu lệnh nhận có thể thực hiện được bởi vì có các thông điệp khác trong kênh, khi kênh không rỗng (not empty); thì thực hiện câu lệnh, gỡ bỏ đi thông điệp ở đầu hàng đợi và gán giá trị của nó cho các biến trong lệnh nhận.

Kênh là một phần của các trạng thái tính toán. Các câu lệnh gửi và nhận là các thực thi nguyên tử.

Khi kênh bị đầy, thì có thể xảy ra hiện tượng mất các thông điệp thay vì là khóa kênh không sử dụng.

Để kiểm tra một kênh là đầy hay rỗng ta dùng các hàm tiền định nghĩa để kiểm tra: fullempty, và hàm ngược của chúng là nfullnempty.

Để kiểm tra số thông điệp trong một kênh ch thì ta dùng hàm len(ch), hàm này trả về kết quả là số thông điệp trong kênh ch.

d. So sánh kênh gặp và kênh đệm

Kênh gặp và kênh đệm đều có những ưu nhược điểm riêng, tùy vào hoàn cảnh sử dụng mà ta dùng kiểu tương ứng. Ta so sánh kênh gặp và kênh đệm theo một số tiêu chí.

Về sự hiệu quả, kênh gặp hiệu quả hơn. Không có biến kết hợp với kênh gặp, nên nó không làm tăng không gian trạng thái. Kênh đệm thì làm tăng không gian trạng thái vì mỗi hoán vị của thông điệp làm tăng dung lượng kênh và các thông điệp cũng có nhiều trường trong đó.

Về mặt cảm quan, thì kênh đệm chỉ tiện lợi hơn bởi vì nó có thể cài đặt cùng với các lệnh lặp và một quá trình thêm vào để lưu nội dung kênh. Kênh đệm cũng hỗ trợ việc mô hình hóa trực tiếp các hệ thống không đồng bộ nơi mà xử lý việc truyền dữ liệu mà không bị khóa.

Khi dùng kênh đệm thì cần lưu ý đến dung lượng của kênh và không gian trạng thái phải đủ nhỏ để phép kiểm chứng khả thi.

Một phần của tài liệu (LUẬN văn THẠC sĩ) kết hợp phương pháp kiểm chứng mô hình và các kỹ thuật kiểm thử phần mềm làm tăng độ tin cậy của hệ thống phần mềm (Trang 40 - 43)

Tải bản đầy đủ (PDF)

(79 trang)