首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> VC 教學

在 C++ 程式中引入邏輯流程控制:協同程式與狀態機模式

     編輯:VC 教學

程式執行流程與業務邏輯流程常不一致。以同步 Socket 讀取 HTTP 請求為例,巢狀迴圈與狀態分散導致代碼難維護。本文探討如何將邏輯流程顯式建模,提升可讀性與擴充性。

問題示範:傳統同步讀取


void read(HTTP_REQUEST& req) {
    read(req.header);
    read(req.body, req.header);
}
void read(HTTP_REQUEST_HEADER& hdr) {
    string line = read_line();
    parse_request_line(line, hdr.method, hdr.uri, hdr.version);
    while (true) {
        line = read_line();
        if (line.empty()) break;
        parse_header_field(line, hdr);
    }
}
void read(BYTE*& body, HTTP_REQUEST_HEADER& hdr) {
    string te = hdr.fields["Transfer-Encoding"];
    if (te != "chunked")
        body = read_bytes(hdr.fields["Content-Length"]);
    else {
        while (true) {
            string chunk_hdr = read_line();
            DWORD sz = atoi(chunk_hdr.c_str());
            if (sz == 0) break;
            BYTE* chunk = read_bytes(sz);
            body = append(body, chunk, sz);
        }
    }
}
// 底層讀取緩衝...

缺點:控制流分散、錯誤處理分散、難以單元測試、阻塞執行緒。

解決方案一:狀態機顯式化

定義枚舉狀態,每個狀態對應一個處理函式,主迴圈驅動狀態轉移:


enum class HttpState { RequestLine, Headers, BodyLength, BodyChunked, ChunkHeader, ChunkData, Done, Error };

class HttpParser {
    HttpState state = HttpState::RequestLine;
    Buffer buffer;
    HTTP_REQUEST req;
public:
    bool feed(const char* data, size_t len) { /* 追加緩衝 */ }
    bool process() {
        while (state != HttpState::Done && state != HttpState::Error) {
            switch (state) {
                case HttpState::RequestLine:  return parseRequestLine();
                case HttpState::Headers:      return parseHeaders();
                case HttpState::BodyLength:   return readBodyLength();
                case HttpState::BodyChunked:  return readChunkedBody();
                // ...
            }
        }
        return state == HttpState::Done;
    }
};

優點:邏輯集中、易測試、可中斷恢復、支援非同步事件驅動。

解決方案二:協同程式

C++20 協同程式可將非同步邏輯寫成同步風格:


#include <coroutine>

task<HTTP_REQUEST> read_http_request(AsyncSocket& sock) {
    auto header = co_await read_header(sock);
    auto body = co_await read_body(sock, header);
    co_return HTTP_REQUEST{header, body};
}

編譯器自動生成狀態機,代碼線性、無回呼地獄。需支援 C++20 協同程式的編譯器(MSVC /std:c++20, GCC -fcoroutines, Clang -fcoroutines-ts)。

解決方案三:Boost.Asio / libuv 非同步框架

產業級非同步 I/O 框架,以完成處理器回呼或 C++20 awaitable 形式表達邏輯流程,自動管理緩衝、超時、取消、背壓等。

選型建議

方案適用場景學習曲線
手寫狀態機簡單協議、嵌入式、無 C++20 環境低
C++20 協同程式現代專案、複雜非同步邏輯、團隊接受新標準中
Boost.Asio高效能網路服務、成熟生態、長期維護專案中高

核心原則

  • 將隱式控制流顯式化:狀態、轉移、動作一目了然。
  • 關注點分離:協議解析、I/O 操作、業務邏輯解耦。
  • 可測試性:狀態機可餵入模擬資料單元測試,無需真實網路。

引入邏輯流程控制,是從「能跑」邁向「好維護、好擴充、好測試」的關鍵步驟。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved