SORU
30 EKİM 2009, Cuma


C durum makinesi tasarımı

Karışık C ve C küçük bir proje işçiliği yapıyorum . Bir küçük-ish işçi benim konuyu bir kalp-makine state Binası ediyorum.

Seninle Guru diye merak ettim-makine durumu tasarım teknikleri paylaşmak istiyorum.

NOT:Öncelikle denenmiş ve test uygulama teknikleri peşindeyim.

GÜNCELLEME:Büyük giriş ÇOK toplandı göre, bu mimari yerleştiğim:

alt text

CEVAP
30 EKİM 2009, Cuma


Önce tasarladım bu durum makinaları (C, C) struct bir dizi ve bir döngü göstermektedir. Yapısı temelde devlet ve bir olay (arama için) ve yeni bir devlet, böyle bir şey döndüren bir işlev içerir:

typedef struct {
    int st;
    int ev;
    int (*fn)(void);
} tTransition;

Basit tanımlar ile durumları ve olayları tanımlamak (ANY olanlar özel işaretleri, aşağıya bakınız):

#define ST_ANY              -1
#define ST_INIT              0
#define ST_ERROR             1
#define ST_TERM              2
: :
#define EV_ANY              -1
#define EV_KEYPRESS       5000
#define EV_MOUSEMOVE      5001

Sonra geçişler tarafından çağrılan tüm işlevleri tanımlayın:

static int GotKey (void) { ... };
static int FsmError (void) { ... };

Bu işlev değişkenleri alır ve devlet makine için yeni bir devlet dönmek için yazılır. Hepsi aynı form izleyin ve parametreleri almak için, kullanın "" bilgi, gerektiğinde geçiş için. değişkenleri global yapılmış var Bu kadar kötü değil sesler beri FSM genellikle kilitli içeride bir tek derleme birimi ve tüm değişkenler için statik birimi (bu yüzden kullanılan tırnak "genel" yukarıda onlar ortak daha global anlamda). Tüm bütünsel olarak bakım gerektirir.

Geçişler dizi sonra tüm olası geçişleri ve bu geçişler için çağırılır işlevleri (tüm yakalamak sonuncusu da dahil olmak üzere) tanımlar:

tTransition trans[] = {
    { ST_INIT, EV_KEYPRESS, &GotKey},
    : :
    { ST_ANY, EV_ANY, &FsmError}
};
#define TRANS_COUNT (sizeof(trans)/sizeof(*trans))

TELEVİZYON işleyişini sonra nispeten basit bir döngü haline:

state = ST_INIT;
while (state != ST_TERM) {
    event = GetNextEvent();
    for (i = 0; i < TRANS_COUNT; i  ) {
        if ((state == trans[i].st) || (ST_ANY == trans[i].st)) {
            if ((event == trans[i].ev) || (EV_ANY == trans[i].ev)) {
                state = (trans[i].fn)();
                break;
            }
        }
    }
}

Bahsettiğin gibi yukarıda, not kullanım ST_ANY EV_ANY gibi joker karakterleri sağlayan bir olay için bir arama fonksiyonu olursa olsun mevcut durumu ve garanti, eğer sana ulaşmak sonunda değşim dizi, belirten bir hata sizin FSM bulunmadı inşa doğru.

Kodu pek çok iletişim projeleri üzerinde buna benzer, katmanlı OSI modelinin ilk uygulaması ve gömülü sistemler için protokoller gibi kullandım. Büyük avantajı geçişler dizi değişen basitlik ve göreceli kolaylığı.

Günümüzde daha uygun olabilecek üst düzey soyutlamalar olacak hiç şüphem yok ama yapısı aynı bu tür kaynatın hepsi şüpheli.


ldog yorum Devletleri olarak, bütünsel tamamen tüm fonksiyonları için bir işaretçi yapısı (ve olay döngü kullanarak) geçerek önleyebilirsiniz. Bu teknoloji harikasi makineleri müdahale olmaksızın yan yana çalıştırmak için izin verecektir.

Sadece makine ile ilgili verileri (minimum devlet) tutan bir yapı türü yaratmak ve global yerine bunu kullanın.

Nedeni ben zaten nadiren yapılır çünkü çoğu devlet makineler yazdım hep tek tip (one-off-işlemi başlatın, yapılandırma dosyası okuma örneği), gerek çalıştırmak için daha fazla örnek. Ama eğer birden fazla çalıştırmak istiyorsanız değeri vardır.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Android Authority

    Android Auth

    3 NİSAN 2011
  • kimberly p

    kimberly p

    23 Ocak 2010
  • Majestic Casual

    Majestic Cas

    28 NİSAN 2012