2017-10-08 103 views
0

我在編程中遇到了一個問題,我沒有找到任何方便快捷的執行解決方案。暫停並恢復C++函數

我試圖實現某種狀態機:在入口處理一個字節,處理它,更改狀態,循環等...目的是處理字節流而不需要任何內存緩衝區(處理字節數字節)。

的類應該是這樣的:

class Decoder { 
    void next() { 
    int i = 0; 
    std::cout << i << "\n"; 
    i++; 
    yield(); // pseudo code => should stop the function and save the current state (or simply not freeing allocated variables) 
    std::cout << i << "\n"; 
    } 
}; 

Decoder decoder = Decoder(); 
decoder.next(); // print 1 
std::cout << "1.5" << "\n"; // print 1.5 
decoder.next(); // print 2 

一個解決辦法是建立一個step財產保存步驟,然後用開關恢復,但性能會受到強烈衝擊。我想知道是否有辦法退出函數的執行,然後再恢復它?

要說清楚,我不想暫停整個程序,只是一個函數。暫停這樣的功能將返回給調用者並繼續執行程序,直到調用下一個next。此外,我想避免線程和標準差(我更喜歡所有的環境代碼)。最後,如果您有任何其他替代方案來解決我的問題:爲內存有效地處理字節流,我願意接受您的建議。

感謝您的幫助。

+2

_To清楚,我不想暫停整個程序,只有一個function._所以換句話說,你想要線程('std :: thread')? –

+2

您在問題中缺少的術語是合作例程。沒有內置的方式(但是),但boost庫有一個協同例程框架的實現。 – StoryTeller

+3

「我想避免... std」?爲什麼?您確實知道標準庫是* portable *,並且所有符合標準的C++編譯器都應該實現所有這些(使其可用於所有「環境」)。不使用標準圖書館並重新發明輪子將使您實際上成爲一家只有可能僱主經驗不足的單店。 –

回答

0

我相信你可以只是使用這兩種方式實現:

選項1:成員國

分裂狀態機的對象爲一個單獨的對象,那麼你所有的局部變量轉換爲成員。

對於此步驟的每一步,請保存一個State成員,表示您在整個程序執行過程中現在在哪裏。

每次您輸入next()檢查您的狀態對開關,並調用該步驟指定的內部方法。

每個這樣的步驟方法模擬代碼執行到連續的yields之間。

struct Decoder { 
    void next() { 
    switch (_step) { 
     case s1: 
     step1(); 
     _step = s2; 
     return; 

     case s2: 
     step2(); 
     _step = s1; 
     return; 

     default: 
     return; // handle error... 
    } 
    } 

private: 
    enum Step { s1, s2 }; 

    Step _step = s1; 
    int _i = 1; 

    void step1() { 
    std::cout << _i << "\n"; 
    _i++; 
    } 

    void step2() { 
    std::cout << _i << "\n"; 
    } 
}; 

int main() { 
    Decoder decoder = Decoder(); 
    decoder.next(); // print 1 
    std::cout << "1.5" << "\n"; // print 1.5 
    decoder.next(); // print 2 
} 

選項2:螺紋和信令

使用一個線程,使用原生API運行過程中(例如在pthread_create在POSIX平臺)的你能。

你的線程裏面,你想yield每一次,等待一個條件變量,如:

struct Decoder { 
    Decoder() { 
    _thread = std::thread { &Decoder::worker, this }; 
    } 

    ~Decoder() { 
    _thread.join(); 
    } 

    void next() { 
    std::lock_guard<std::mutex> lock(_mutex); 
    _work = true; 
    } 

private: 
    void wait() { 
    std::unique_lock<std::mutex> lock(_mutex); 
    _cond.wait(lock, [this](){return _work;}); 
    } 

    void worker() { 
    wait(); 

    int i = 0; 
    std::cout << i << "\n"; 
    i++; 

    wait(); 

    std::cout << i << "\n"; 
    } 

    std::thread _thread; 
    std::mutex _mutex; 
    std::condition_variable _cond; 
    bool _work = false; 
}; 

int main() { 
    Decoder decoder; 
    decoder.next(); // print 1 
    std::cout << "1.5" << "\n"; // print 1.5 
    decoder.next(); // print 2 
}