2017-10-08 17 views
0

편리하고 빠른 실행 솔루션을 찾지 못한 프로그래밍 문제가 있습니다.C++ 함수 일시 중지 및 다시 시작

저는 상태 머신의 일종을 구현하려고합니다 : 엔트리에서 1 바이트 걸리고, 프로세스를 변경하고, 상태, 루프 등을 변경하려고합니다. 목적은 메모리 버퍼를 필요로하지 않고 바이트 스트림을 처리하는 것입니다 바이트).

해야는 다음과 같습니다 클래스 :

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이 호출 될 때까지 프로그램 실행을 계속합니다.

또한 스레드와 std를 피하고 싶습니다 (모든 환경 코드 선호). 마지막으로, 내 문제에 대한 다른 대안이 있다면 : 메모리에 효율적으로 바이트 스트림을 처리하십시오. 제안에 대해 공개적입니다.

도움 주셔서 감사합니다.

옵션 1 : 회원 상태를

분할 별도의 객체로 상태 머신 개체를 회원들에게 모든 로컬 변수를 변환

+2

_to는 분명히, 나는 전체 프로그램을 일시 정지하고 싶지 않은, 단지 function._ 그래서 , 즉 스레드 ('std :: thread')를 원합니까? –

+2

질문에 누락 된 용어는 공동 루틴입니다. 아직 내장 된 방법은 없지만 부스트 라이브러리에는 공동 루틴 프레임 워크가 구현되어 있습니다. – StoryTeller

+3

"나는 ... 표준을 피하고 싶습니다." 왜? 당신은 표준 라이브러리가 * portable *이고 모든 준수하는 C++ 컴파일러가 모든 것을 구현해야한다는 것을 알고 있습니다 (모든 "환경"에서 사용 가능하게 만듭니다).표준 라이브러리를 사용하지 않고 휠을 다시 만들면 가능한 한 고용주를위한 거의 경험이없는 1 인 샵이됩니다. –

답변

0

나는이 두 가지 방법을 사용하여 단지 것을 달성 할 수 있으리라 생각합니다.

각 단계마다 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 
}