부스트 스테이트 머신을 사용하려고하는데 무한 루프로 머신을 돌릴 때 세그멘테이션 폴트가 발생했습니다. 기본적으로 I는 과급 상태 머신 펑 예와 같은 예는 아래 가지고부스트 메타 상태 머신 무한 루프 세그 폴트
유일한 차이점은 지금 "합니다 Event1"를 트리거 따라서 루프를 생성 최대한 빨리 State4 입력으로 발생하기 때문이다. 이 작업은 수천 번 반복되지만 그 다음에는 오류가 발생합니다. 어떤 종류의 UML 규칙을 위반하고 스택을 오버플로합니까? 기본적으로 하나의 블로킹 이벤트 만 있고 다른 모든 상태를 자동으로 트리거 한 다음 State4에서 종료합니다 (실제로는 네트워크에서 메시지를 기다리는 블로킹 호출 일 것입니다). 스택을 날려 버리지 않으려면 어떻게 메타 상태 머신을 사용하여 이것을 올바르게 구현할 수 있습니까?
여기 내 문제의 원인이되는 소스 코드를 포함 시켰습니다
UPDATE : http://pastebin.com/fu6rzF0Q
이 기본적으로 다음과 같은 변화를 제외하고 펑 프론트 엔드의 예는 다음과 같습니다
추가를 "차단"통화 기능 차단 :
struct BlockingCall {
template <class EVT, class FSM, class SourceState, class TargetState>
void operator()(EVT const &, FSM &, SourceState &, TargetState &) {
std::cout << "my_machine::Waiting for a thing to happen..." << std::endl;
// Pretend I'm actually waiting for something
std::this_thread::sleep_for(std::chrono::milliseconds(100));
std::cout << "my_machine::OMG the the thing happened!" << std::endl;
}
};
그리고 마지막으로 트란 sition 테이블 :
더 이상 State1 정에 State4에서 이동 트리거해야하는 경우가 있음을 struct transition_table : mpl::vector<
// Start Event Next Action Guard
// +---------+-------------+---------+---------------------+----------------------+
Row < State1 , none , State2 >,
Row < State2 , none , State3 , State2ToState3 >,
Row < State3 , none , State4 , none , always_false >,
// +---------+-------------+---------+---------------------+----------------------+
Row < State3 , none , State4 , State3ToState4 , always_true >,
Row < State4 , none , State1 , BlockingCall >
// +---------+-------------+---------+---------------------+----------------------+
> {};
알 수 있습니다. 이 코드는 의심의 여지없이 seg 오류를 일으키며 스택 추적은 1000 초 길이입니다.
내가 기다리는 시간에 관계없이 나는 항상 결국 오류가 있음을 알아야합니다. 나는 수면을 1 - 100로 바꾸면서 놀았으며 결국 죽을 것입니다. 단일 루프가 완료되면 스택을 언 롤링 할 방법이 필요합니다. 2
UPDATE 그래서 나는 무한 루프에서 이벤트를 트리거 할 때 내가 독방 감금 잘못을하지 않는 것을 발견했다.
struct transition_table : mpl::vector<
// Start Event Next Action Guard
// +---------+-------------+---------+---------------------+----------------------+
Row < State1 , none , State2 >,
Row < State2 , none , State3 , State2ToState3 >,
Row < State3 , none , State4 , none , always_false >,
// +---------+-------------+---------+---------------------+----------------------+
Row < State3 , none , State4 , State3ToState4 , always_true >,
Row < State4 , event1 , State1 , none >
// +---------+-------------+---------+---------------------+----------------------+
> {};
가 그럼 난 다음에 메인 프로그램을 변경 :
먼저 내가 원래 예제로 다시 전환 테이블을 설정 : 여기에 내가 무슨 짓을
void test() {
my_machine p;
// needed to start the highest-level SM. This will call on_entry and mark the
// start of the SM
// in this case it will also immediately trigger all anonymous transitions
p.start();
// this event will bring us back to the initial state and thus, a new "loop"
// will be started
while (true) {
p.process_event(event1());
}
}
그리고 지금은이 전속력으로 (잠을 자지 않고) 달렸고 나는 세그 폴트하지 않았다. 이것을 토대로 상태 머신을 시작하고 내부 이벤트를 실행하고 처리하는 방법이없는 것 같습니다. 맞습니까? 나는 적어도 외부에서도 어떤 과정을 일으켜야 만 하는가?
UPDATE 3 궁극적으로 나의 목표는 다음 그림과 같이 구현하는 것입니다 : 이
내 의도는 상태 머신을 시작하는 것입니다, 그리고 그것은 단순히 더 이상 개입하지 않고 수신 메시지를 기다립니다 .
[MCVE] –
@ m.s를 게시해야합니다. 귀하의 추천으로 내 질문을 업데이트했습니다. – user985030
특정 도구에서 Wesson을 구현하는 방법에 대해 답변을 드릴 수는 없지만 직접 언급 만 할 것입니다. UML 관점에서 볼 때 립은 유한 한 가치가 없다. 사실 아주 자주 주 기계가 무한대로 진행되지만 대개 하나 이상의 주정부가 최종판으로 간주됩니다. 그러나 실제 구현으로 갈 때 많은 문제가 발생할 수 있으며 무한 루프는 이러한 문제를 드러내는 경향이 있습니다. 툴의 한계로 인해 절대적으로 유효한 UML 상태 머신이 당신이 선택한 툴로 구현 될 수 없을 수도 있습니다. – Ister