Máy trạng thái hữu hạn là công cụ để đạt được kết thúc nhất định. Như bất kỳ công cụ nào, chúng cũng có thể bị lạm dụng.
Chúng không phải là công cụ duyên dáng nhất, nhưng công việc mà họ giỏi là không thể đạt được bằng các phương tiện khác (và thường là bất kỳ cách tiếp cận nào khác sau đó sẽ trở thành một đống lộn xộn khủng khiếp gấp hàng nghìn lần so với máy).
Công việc đang hoạt động trong điều kiện trạng thái chờ cổ điển bị cấm.
Tôi phải đọc màn hình cảm ứng. Để đọc vị trí, tôi phải trao đổi khoảng 15 lệnh trên SPI. Tôi cần 100 bài đọc tốt một giây. Tôi phải chờ khoảng 1 micro giây sau mỗi lệnh, cho lá cờ bận rộn tương ứng biến mất trước khi tôi có thể tiếp tục. Ngoài ra còn có một số hoạt động khác phải đạt được trên cùng một giao diện, như thiết lập độ tương phản, thay đổi chế độ, bật hoặc tắt đèn nền, đọc nhiệt độ. Nếu tôi thực hiện while(BUSY_BIT);
cho mỗi lần chờ, tôi sẽ ăn hết tất cả CPU trong giây lát. Nếu tôi đã làm sched_yield()
hoặc usleep(1)
, tôi sẽ không bao giờ đạt được số lượng readouts mà tôi muốn. Cách duy nhất là một máy trạng thái hữu hạn.
Nhưng có nhiều cách để làm cho máy trạng thái hữu hạn phát đẹp. Ẩn máy đằng sau hậu trường và cung cấp cho các chức năng của nhà phát triển để làm việc.
Kinh nghiệm làm việc của tôi cho đến nay bị chi phối bởi 2 hệ thống dựa trên 3 máy trạng thái hữu hạn khác nhau.
- cổng thông tin web lớn, trong mỗi bước bạn truy xuất một số dữ liệu từ cơ sở dữ liệu và dựa trên đó, chuẩn bị nhiều truy vấn hơn. Trong bước cuối cùng bạn sử dụng dữ liệu để tạo HTML. Mỗi tác vụ - một mô-đun trang web - được triển khai như một lớp PHP kế thừa từ công cụ. Nhà nước được bảo tồn trong các biến lớp. Mỗi bước là một chức năng riêng biệt. Vào cuối một bước, các truy vấn được lưu trữ đã được tối ưu hóa và gửi đến động cơ, thông qua bộ nhớ cache và các câu trả lời được cung cấp lại cho bản gốc.
- thiết bị được nhúng với nhiều hệ thống phụ. Task Pump được sử dụng. Mỗi mô-đun đăng ký một trình xử lý được gọi nhiều lần trong một giây từ vòng lặp chính. Trình xử lý có thể bảo toàn trạng thái trong các biến tĩnh hoặc lớp, với các trạng thái. Sự đa nhiệm hợp tác này cho phép lưu lượng bộ nhớ nhỏ hơn nhiều so với chạy tất cả trong các luồng riêng biệt, cho phép ưu tiên thủ công các tác vụ bằng cách đăng ký chúng hai lần, và có chuỗi chạy ở mức ưu tiên cao, làm lu mờ phần còn lại của hệ thống.
- thông dịch viên bán. Màn hình cảm ứng đó. Các cuộc gọi chức năng và trạng thái chờ của chúng được đăng ký, nhưng mỗi trạng thái được gọi chỉ một lần, sau đó bị xóa khỏi hàng đợi của chương trình. Trình thông dịch được gọi là nhiệm vụ của taskpump, thực hiện một số chức năng giới hạn cho đến khi gặp phải một hàm được đánh dấu là trạng thái chờ (hoặc vượt quá số hàm được gọi). Sau đó, nó tiếp tục cho đến khi trạng thái chờ biến mất. Các công việc khác enqueue công việc như (đôi khi dài) trình tự của các chức năng được thực hiện, sau đó chờ kết quả. Bằng cách này tôi có thể giới hạn số lượng trạng thái tôi cần để tạo ra khoảng 4 nơi tôi cần kết quả. Nếu lệnh là "gửi đi, không bao giờ kiểm tra kết quả" như "thiết lập tương phản", họ không cần các trạng thái rời rạc cả. Vì vậy, các trạng thái thực tế là "chờ sự kiện và đăng ký dữ liệu được yêu cầu", "chờ đợi để đo lường" và "đọc kết quả và gán chúng đúng cách".
Mã sẽ đơn giản gấp hai lần và rõ ràng hơn ba lần nếu được viết theo cấu trúc hoặc tuần tự. Ngoại trừ nó sẽ không làm việc, hoặc sẽ làm việc với hiệu suất abysmal.
Nguồn
2010-02-02 11:22:12
liên quan: http://stackoverflow.com/questions/1647631/c-state-machine-design – jldupont
Là một Pastafarian sùng đạo , FSM luôn tốt;) – richo
Không bao giờ làm hỏng toàn bộ cách tiếp cận vì bạn đang xem xét việc triển khai kém. Bất cứ điều gì không có giấy tờ/khó gỡ lỗi là xấu, nhưng nó là việc thực hiện đó là xấu. –