Quy trình tuần tự

Một phần của tài liệu đặc tả và kiểm chứng các phần mềm tương tranh (Trang 27)

Các tiến trình trong FSP được chia làm 3 loại:

- Các tiến trình cục bộ (local process) được định nghĩa là một trạng thái trong một tiến trình cơ bản [1].

- Tiến trình cơ bản (primitive process) được xác định bởi tập hợp các tiến trình cục bộ. Một tiến trình cục bộ được xác định bằng cách sử dụng STOP, ERROR, tiền hành động (Action prefix) và lựa chọn (|, choice) [1].

- Tiến trình tuần tự ( sequential process) là một tiến trình có thể kết thúc. Một tiến trình có thể kết thúc nếu một tiến trình cục bộ END có thể được với tới từ trạng thái bắt đầu của nó [1].

Tiến trình cục bộ END: Tiến trình cục bộ END biểu thị trạng thái mà tiến trình kết thúc thành công. Một tiến trình đúng đắn khi không có hành động nào tiếp theo xảy ra sau END. Về mặt ngữ nghĩa nó tương tự như STOP. Tuy nhiên, STOP là một trạng thái mà tiến trình tạm ngưng quá sớm, thường là do deadlock. STOP được sử dụng khi ta muốn kết thúc một tiến trình [1]. Ví dụ sau mô tả tiến trình hẹn giờ một quả bom nổ trong đó trạng thái E là trạng thái kết thúc:

Đặc tả và kiểm chứng các phần mềm tương tranh

Hình 2.3.1c [1] : Tiến trình tuần tự BOMP

Sự tổng hợp các tiến trình tuần tự: Nếu Q là một tiến trình tuần tự, P là một tiến trình cục bộ, sau đó P;Q biểu diễn cho sự tổng hợp tuần tự như vậy khi P kết thúc, P;Q sẽ trở thành tiến trình Q [1].

Nếu chúng ta định nghĩa tiến trình SKIP = END then P; SKIP ≡ P and SKIP; P ≡ P. Một sự tổng hợp tuần tự trong FSP luôn luôn có dạng: SP1;SP2;….;SPn;LP [1]

Nơi SP1;…;SPn là sự tổng hợp tuần tự và LP là tiến trình cục bộ. Một sự tổng hợp tuần tự có thể xuất hiện ở bất cứ chỗ nào trong định nghĩa của một tiến trình cơ bản mà một tiến trình cục bộ tham chiếu đến có thể xuất hiện [1].

Ví dụ tiến trình P123 và LOOP:

Hình 2.3.1d[1]: Sự tổng hợp tuần tự LOOP

Sự tổng hợp song song các tiến trình tuần tự: Sự tổng hợp song song SP1 || SP2 của hai tiến trình tuần tự SP1 và SP2 kết thúc khi cả hai tiến trình cùng kết thúc. Nếu kết thúc có thể tới được trong SP1 || SP2 thì nó là tiến trình tuần tự [1].

Hình dưới cho một ví dụ về sự tổng hợp song song của tiến trình tuần tự.:

Hình 2.3.1e[1] : Sự tổng hợp song song hai tiến trình tuần tự. 2.3 LTS (Labelled Transition System)

2.3.1 LTS

Khái niệm: Về cơ bản LTS[1][2] (Lebelled Transition System) giống FSP, mỗi mô tả FSP có một mô tả máy trạng thái (LTS) tương ứng. Mỗi LTS tương ứng với một quá trình FSP là một đồ thị. Ta lấy ví dụ LTS mô tả bài toán “bữa tối của triết gia” [1]:

PHIL = (sitdown->right.get->left.get ->eat->left.put->right.put ->arise->PHIL).

FORK = (get -> put -> FORK). ||DINERS(N=5)= forall [i:0..N-1] (phil[i]:PHIL

Đặc tả và kiểm chứng các phần mềm tương tranh

Phân tích mẫu LTS này ta được 2 mô hình tương ứng:

Hình 2.3.1a: Máy trạng thái PHIN

Hình 2.3.1b: Máy trạng thái FORK

2.3.2 Deadlock

2.3.2.1 Khái niệm

Deadlock xảy ra trong hệ thống khi tất cả các tiến trình của hệ thống đều bị chặn hoặc không đủ điều kiện để tiến trình đó hoạt động.

Một ví dụ về deadlock điển hình là: “bữa tối của triết gia”. Một bàn ăn có 5 cái ghế, 5 vị triết gia cùng ngồi vào chiếc bàn. Khi bày đũa, người phục vụ chỉ để vào giữa mỗi người 1 chiếc đũa. Như vậy 2 bên mỗi vị triết gia đều có 2 chiếc đũa nhưng nếu người này cầm đũa thì người kia sẽ không có:

Hình 2.3.2.1a: Bữa tối của triết gia[1]

Nếu số đũa được chia đều ra cho năm người, như vậy mỗi người sẽ có một chiếc đũa. Cả năm người sẽ không thể thực hiện bữa ăn của mình với một chiếc đũa được, khi đó deadlock xảy ra.

Hình 2.3.2.1b: Deadlock[1]

2.3.2.2 Phân tích Deadlock (adsbygoogle = window.adsbygoogle || []).push({});

Đặc tả và kiểm chứng các phần mềm tương tranh

vậy có thể không tham gia vào các hành động tiếp theo. Trong FSP trạng thái deadlock này được biểu diễn bằng một biến cục bộ STOP[1].

Nhìn chung, hệ thống tương tranh với rất nhiều tiến trình xảy ra rất có thể sẽ xảy ra bế tắc. Việc kiểm tra, phân tích deadlock trong đồ thị LTS là hết sức quan trọng. Nó đảm bảo cho việc thiết kế chương trình phần mềm đúng đắn và chính xác. Công cụ LTSA có sẵn chức nằng phân tích deadlock, chúng ta sẽ nghiên cứu ở phần sau.

2.3.3 Thuộc tính An toàn (safety property)

Khái niệm safety: Thuộc tính an toàn đảm bảo không có lỗi xảy ra trong quá trình thực hiện các tiến trình của một hệ thống tương tranh.

Safety property: Về mặt cú pháp, những tiến trình FSP được thêm vào trước từ khóa property để khẳng định nó là một thuộc tính an toàn. Một thuộc tính an toàn khẳng định tất cả các hành động trong Alphabet của nó đều được nó chấp nhận. Điều này đảm bảo cho hệ thống hoạt động đồng bộ bởi tiến trình an toàn này.

Ví dụ mô tả trạng thái đèn xanh, đỏ của đèn giao thông:

property TRAFICLIGHT = (red -> enter |blue -> exit).

2.3.4 Thuộc tính Liveness (Liveness property)

Khái niệm: Thuộc tính Liveness là thuộc tính quan trọng nhất trong chương hệ thống tương tranh, nó khẳng định khi chương trình kết thúc có đạt trạng thái tốt hay không [1].

Thuộc tính tiến trình (progress): Một đặc tính progress khẳng định tại bất kỳ trạng thái nào của một trong các hoạt động của một thực thi phải xảy ra. Tức là các hoạt động thành công và phải được kết thúc .

Phân tích tiến trình: phân tích tiến trình để tìm ra tập kết thúc của các trạng thái. Tập kết thúc của trạng thái là một tập hợp trong đó một trạng thái có thể truy cập từ mọi trạng thái khác trong tập hợp thông qua một hoặc nhiều chuyển tiếp và không có chuyển tiếp nào từ bên trong tập hợp ra trạng thái bên ngoài tập hợp.

2.4 Công cụ LTSA

LTSA (Labelled Transition System Analiser) là một công cụ hỗ trợ kiểm chứng với đặc tả là LTS. LTSA sử dụng để kiểm tra tính mong muốn và không mong muốn cho tất cả các trình tự có thể có của các sự kiện và hành động [1]. LTSA được tải miễn phí từ trang web [4] chính thức của cuốn sách “Concurrency: State Models and Java Programs second edition [1]”. Ta lấy ví dụ LTSA phân tích một đặc tả LTS cho trạng thái vào, ra của một chiếc ô tô khi qua cầu:

CAR = (enter -> exit -> CAR).

Hình 2.4a: Mô hình hành động của chiếc ô tô

Đặc tả và kiểm chứng các phần mềm tương tranh

Mỗi hành động được chọn trong Animator sẽ điều khiển các hoạt động tương ứng trong mô hình.

2.5 Kết luận

Trong chương này, chúng ta đã tìm hiểu một số khái niệm phần mềm tương tranh, phương pháp mô hình hóa, máy hữu hạn trạng thái FSP và công cụ hỗ trợ kiểm chứng LTSA. Đây là những khái niệm cơ bản mà chúng ta sẽ phải trang bị để có thể thực hiện đặc tả và kiểm chứng thiết kế, cài đặt một phần mềm tương tranh mà chúng ta sẽ tìm hiểu ở hai chương sau.

Chương 3: Kiểm chứng thiết kế

Một bản thiết kế, dù cẩn thận và chi tiết đến đâu cũng có thế tồn tại thiếu sót, chính vì vậy mô hình hóa thiết kế là một cách để kiểm chứng hiệu quả nhất. Phương pháp mô hình hóa được sử dụng rất rộng rãi trong kỹ thuật, ở một phương diện nào đó, mô hình có thể đại diện cho vật chất, mang đầy đủ các tính chất của vật chất. Khi chúng ta kiểm tra trên mô hình sẽ cho kết quả tương đương với ở ngoài thực tế. Trong thiết kế cũng vậy, mô hình hóa thiết kế sẽ cho chúng ta kiểm tra thiết kế một cách toàn diện, xem nó có đúng với yêu cầu bài toán đặt ra không?

3.1 Đặc tả thiết kế bằng FSP

Như chúng ta đã biết ở trên, FSP rất phù hợp cho việc thiết kế một phần mềm tương tranh, tuy nhiên, chúng ta vẫn cần kiểm chứng xem thiết kế liệu có đúng như yêu cầu của bài toán không? LTS Analiser ( LTSA) dùng để phân tích FSP thành các mô hình, thuận tiện cho việc kiểm tra thiết kế. Để thuận tiện cho việc hình dung, chúng ta cùng xem một ví dụ đặc tả thiết kế bằng FSP.

Bài toán “SingleLandBridge” được phát biểu như sau: Trên một con đường có một chiếc cầu hẹp, chiếc cầu chỉ đủ cho một làn xe chạy. Yêu cầu đặt ra là tạo ra một chương trình điều khiển sự ra, vào của ô tô ở hai đầu cầu. Chương trình sẽ cho các ô tô đi tới cầu được qua cầu nếu trên cầu chỉ có ô tô đi cùng chiều hoặc không có ô tô chạy theo hướng ngược lại. Nếu trên cầu có xe đang qua cầu theo hương ngược lại hoặc có ô tô đã chờ ở đầu cầu bên kia trước thì ô tô này phải chờ cho chiếc xe đó qua trước.

Chúng ta hãy cùng nghiên cứu yêu cầu thiết kế cho bài toán. Thiết kế phải thực hiện được nhiệm vụ chỉ cho phép ô tô đó được qua cầu nếu trên cầu có ô tô đi cùng hướng hoặc hướng ngược lại không có ô tô.

Thiết kế của bài toán này đã được đặc tả bằng FSP trong các ví dụ có sẵn của công cụ LTSA. Ví dụ này mang tên “SingleLandBridge”. Tuy nhiên, chúng ta sẽ tìm hiểu chi tiết cách đặc tả thiết kế bằng các máy trạng thái FSP. Ta quy định ô tô qua chiếc cầu sẽ phân thành hai loại là ô tô đỏ (red) đi từ phía tây sang và ô tô xanh (blue) đi từ phía đông sang.

Đặc tả và kiểm chứng các phần mềm tương tranh

Hình 3.1: Mô tả các ô tô đi qua một chiếc cầu hẹp[1]

Trước khi đặc tả hai yêu cầu của thiết kế, chúng ta hãy định nghĩa hai tiến trình ô tô và cầu trước: (adsbygoogle = window.adsbygoogle || []).push({});

Tiến trình ô tô (CAR) có hai hành động là đi vào (enter) và đi ra (exit) khi qua cầu:

CAR = (enter -> exit -> CAR).

Tuy nhiên nếu ô tô đi theo đoàn thì mỗi lần chiếc ô tô dẫn đầu được qua cầu thì cả đoàn của chiếc ô tô đó đều được qua. Ta có thêm một định nghĩa những chiếc ô tô nữa:

CARS = (red:CONVOY || blue:CONVOY).

Trong đó red, blue là những chiếc xe đỏ hoặc xanh, CONVOY là tiến trình mô tả tính chất theo đoàn của những chiếc ô tô. CONVOY được định nghĩa như sau:

CONVOY = [ID]:CAR

ID là số ô tô có trong đoàn ô tô.

Nếu một chiếc ô tô đỏ lên cầu, đồng nghĩa với việc trên cầu đó không có chiếc ô tô xanh nào. Nếu trên cầu đã có ô tô đỏ rồi nhưng do các ô tô đỏ đi cùng chiều nên chiếc ô tô đó vẫn được lên cầu, khi đó số ô tô đỏ trên cầu sẽ tăng thêm một. Ngược lại, khi ô tô đỏ đó rời cầu, số ô tô đỏ sẽ giảm đi một. Nếu trên cầu chỉ có một chiếc ô tô đỏ, khi chiếc ô tô đó rời cầu thì trên cầu sẽ không còn chiếc ô tô nào, ta gọi đó là thuộc tính

ONEWAY. Khi xảy ra ONEWAY, hai đầu cầu bên nào có ô tô tới trước sẽ được qua trước. Ta có định nghĩa tiến trình RED và thuộc tính ONEWAY:

RED[i:ID] = (red[ID].enter -> RED[i+1] |when(i==1)red[ID].exit -> ONEWAY |when( i>1)red[ID].exit -> RED[i-1] )

Thuộc tính an toàn ONEWAY khẳng định chiếc cầu an toàn và cho phép ô tô qua cầu khi trên cầu chỉ có một chiếc ô tô và chiếc ô tô đó đã thoát ra ngoài chiếc cầu:

property ONEWAY = (red[ID].enter -> RED[1] |blue[ID].enter -> BLUE[1] )

Tương tự như vậy ta cũng có tiên trình BLUE: BLUE[i:ID] = (blue[ID].enter -> BLUE[i+1]

|when(i==1)blue[ID].exit -> ONEWAY |when( i>1)blue[ID].exit -> BLUE[i-1] )

Trên chiếc cầu bao giờ cũng chỉ có một loại ô tô, hoặc là ô tô đỏ, hoặc là ô tô xanh. Nếu có cả ô tô đỏ và ô tô xanh thì chắc chắn sẽ xảy ra tai nạn. Khi trên cầu không có ô tô xanh, tức là ô tô đỏ được qua cầu và ngược lại, trên cầu không có ô tô đỏ thì ô tô xanh được qua cầu. Ta có định nghĩa tiến trình cầu:

BRIDGE = BRIDGE[0][0], // cầu trống

Đặc tả và kiểm chứng các phần mềm tương tranh

(when (nb==0) // T là số loại ô tô có trên cầu red[ID].enter -> BRIDGE[nr+1][nb] |red[ID].exit -> BRIDGE[nr-1][nb] |when (nr==0) blue[ID].enter -> BRIDGE[nr][nb+1] |blue[ID].exit -> BRIDGE[nr][nb-1] ).

Bây giờ chúng ra sẽ đặc tả bằng FSP các yêu cầu mà thiết kế phải giải quyết. - Ô tô được lên cầu khi trên cầu không có ô tô đi ngược chiều hoặc có ô tô đi cùng chiều:

NOPASS1 = C[1],

C[i:ID] = ([i].enter -> C[i%N+1]).

- Sau khi tất cả những chiếc xe đi cùng chiều rời cầu, xe ở một trong hai đầu cầu sẽ được phép qua cầu:

NOPASS2 = C[1],

C[i:ID] = ([i].exit -> C[i%N+1]).

||CONVOY = ([ID]:CAR || NOPASS1 || NOPASS2).

||CARS = (red:CONVOY || blue:CONVOY).

||SingleLaneBridge = (CARS || BRIDGE || ONEWAY ).

Tổng hợp tất cả các máy hữu hạn trạng thái FSP ta được một máy dịch chuyển trạng thái có gán nhãn LTS hoàn chỉnh để đặc tả thiết kế bài toán:

/** Concurrency: State Models and Java Programs * Jeff Magee and Jeff Kramer

*/ (adsbygoogle = window.adsbygoogle || []).push({});

/* Single Lane bridge

Red cars go from west to east Blue cars go from east to west */

const N = 3 // number of each type of car range T = 0..N // type of car count

range ID= 1..N // car identities

BRIDGE = BRIDGE[0][0], //initially empty

BRIDGE[nr:T][nb:T] = //nr is the red count, nb the blue count (when (nb==0) red[ID].enter -> BRIDGE[nr+1][nb] |red[ID].exit -> BRIDGE[nr-1][nb] |when (nr==0) blue[ID].enter -> BRIDGE[nr][nb+1] |blue[ID].exit -> BRIDGE[nr][nb-1] ).

Đặc tả và kiểm chứng các phần mềm tương tranh

CAR = (enter->exit->CAR).

/* cars may not overtake each other */ NOPASS1 = C[1],

C[i:ID] = ([i].enter -> C[i%N+1]). NOPASS2 = C[1],

C[i:ID] = ([i].exit -> C[i%N+1]).

||CONVOY = ([ID]:CAR || NOPASS1 || NOPASS2). ||CARS = (red:CONVOY || blue:CONVOY).

||SingleLaneBridge = (CARS || BRIDGE || ONEWAY ). property ONEWAY = (red[ID].enter -> RED[1]

|blue[ID].enter -> BLUE[1] ),

RED[i:ID] = (red[ID].enter -> RED[i+1] |when(i==1)red[ID].exit -> ONEWAY |when( i>1)red[ID].exit -> RED[i-1] ),

BLUE[i:ID] = (blue[ID].enter -> BLUE[i+1] |when(i==1)blue[ID].exit -> ONEWAY |when( i>1)blue[ID].exit -> BLUE[i-1] ).

3.3. Kiểm chứng thiết kế bằng LTSA

Sau khi đã đặc tả xong thiết kế của bài toán bằng FSP chúng ta tiến hành kiểm chứng thiết kế đó bằng cách sử dụng công cụ hỗ trợ kiểm chứng LTSA để phân tích mẫu LTS vừa được tạo ra.

3.3.1 Giao diện của công cụ LTSA

LTSA có giao diện trực quan rất dễ sử dụng như ảnh bên dưới:

Hình 3.3.1: Giao diện công cụ LTSA

Trong cửa sổ giao diện của chương trình có 3 khung nhìn:

- Edit: để soạn thảo mã cho chương trình hoặc hiển thị đoạn mã đã có sẵn. - Output: nơi trả về kết quả khi kiểm tra độ an toàn hoặc khi biên dịch đoạn mã. - Draw: Hiển thị kết quả là các mô hình khi biên dịch đoạn mã LTS.

Chi tiết về 3 khung nhìn này chúng ta sẽ tìm hiểu ở các phần tương ứng tiếp theo. Nếu muốn viết một đoạn mã mới, chúng ta chỉ cần nhấn vào biểu tượng New File hoặc vào thực đơn File chọn New. Khi muốn lưu đoạn mã lại ta nhấn vào biểu tượng Save File hoặc tại hộp chọn File chọn Save, đặt tên cho đoạn mã và chọn OK.

Đặc tả và kiểm chứng các phần mềm tương tranh

Nếu muốn mở một đoạn mã có sẵn, nhấn và biểu tượng Open file hoặc tại thực đơn File chọn Open… .

Khi công việc chuẩn bị mã đã xong, ta tiến hành kiểm tra đoạn mã:

3.3.2 Check safety

Check safety sẽ kiểm tra xem chương trình của bạn đã được thiết kế có an toàn hay không? Chương trình sẽ phân tích những tiến trình có trong thiết kế của bạn và phân tích xem trong quá trình các tiến trình đó hoạt động có xảy ra deadlock hay không?

Tại thực đơn Check chọn Safety (adsbygoogle = window.adsbygoogle || []).push({});

Hình 3.3.2: Kết quả hiển thị sau khi check safety

Trên hình vẽ, công cụ LTSA đã phân tích tất cả các máy trạng thái được tạo ra để kiểm tra xem thiết kế có an toàn không? Cụ thể trong bài toán này chúng ta có kết quả kiểm tra là “ No deadlock/errors” tức là thiết kế không có lỗi và không có deadlock.

3.3.3 Check Progress

Check progess có tác dụng tìm ra những hành động có vi phạm hay không, điển hình là hành động đó không có trạng thái kết thúc và không thể thực hiện được.

Một phần của tài liệu đặc tả và kiểm chứng các phần mềm tương tranh (Trang 27)