2012-06-25 139 views
1

我試圖在C中實現有限狀態機,並且需要它非常快速。 所以我決定用函數指針爲 「國」:有限狀態機實現

void *state1(void){ /* function body here */ } 
void *state2(void){ /* ... */ } 
void *state3(void){ /* ... */ } 

然後,主FSM循環可以很簡單:

void *(*fp)(void); 
fp = state1; 

while(fp) 
    fp = fp(); 

有一個問題:

1)它是可能避免在函數返回類型中使用void指針?理想情況下,狀態函數應該有一些類型定義的類型,以確保在FSM中只能使用這種類型的函數。

2)在C語言中實現FSM的傳統方法是使用enum進行狀態和基於開關的調度器循環,因此與基於函數指針的實現相比,會有一個間接級別。
但我不確定,那裏的指令緩存或分支預測有一些問題嗎?換句話說,是否存在可以超越我的解決方案的實現?

謝謝。

+1

我有聞到微型優化嗎?狀態機需要運行幾毫秒? –

+0

@Seva Alekseyev有些州比較大而且速度慢,但有些非常小而且簡單。當FSM處於「大」狀態之一時,性能並不重要,但小型狀態必須儘可能快地執行。 –

+0

如果您希望速度更快,請使用單熱編碼狀態機。你過早的優化不會很長。你最好編寫可讀,可維護和可擴展的代碼。另外,對於C++ - http://www.boost.org/doc/libs/1_49_0/libs/statechart/doc/index.html – 2012-06-25 04:08:12

回答

3

要在C中創建一個像這樣的遞歸類型定義,您需要在該行的某處使用struct,因爲您無法「轉發聲明」typedefs。在循環

struct state { 
    struct state (*func)(void); 
}; 

然後:例如,你可以用一個struct中的函數指針

struct state state = { state1 }; 

while (state.func) { 
    state = state.func(); 
} 
0

1)typedef void(*state_fp)(void);

state_fp state1(void) { } 

2)取決於,小環與內置到函數的代碼會比使函數調用更快。例如一個switch語句,其中每個狀態都在switch語句中實現,但是,如果case語句過多,這將在函數調用下面退化

+0

這將需要在返回時進行強制轉換,因爲函數返回的類型不同作爲指向函數本身的指針的類型(它比OP更好,至少你從一個函數指針類型轉換到另一個函數指針類型,所以它是很好定義的)。 – caf

1

C中不可能聲明一個返回指向函數的指針的函數屬於自己的類型。而且,你不能使用void *,因爲C不允許在函數和對象指針之間進行轉換。相反,您可以使用:

typedef void (*generic_func_ptr)(void); 
typedef generic_func_ptr (*state_func_ptr)(void); 
generic_func_ptr state1(void), state2(void), state3(void); 
state_func_ptr fp; 

while(fp) 
    fp = (state_func_ptr)fp(); 

醜,但它的作品。相反,我會考慮使用switch語句。對於實現狀態機來說它更加清潔。

3

在這裏,你可能會發現你的問題的答案:http://code.google.com/p/fwprofile/

這是一個開放源代碼版本(GNU GPLv3)採用C語言實現的 。該概念和實現非常適合在關鍵任務應用程序中使用 。有部署在工業 應用程序。