문제

Bjarne Stroustrup의 C ++ 프로그래밍 언어의 일부 연습을 진행하고 있습니다. 나는 12 장 말에 문제 11에 의해 혼란 스러워요 :

(*5) 이벤트 중심 시뮬레이션을 작성하기위한 라이브러리를 설계하고 구현합니다. 힌트:u003Ctask.h> . ... 클래스 작업의 대상은 상태를 저장하고 해당 상태를 복원하여 코 루틴으로 작동 할 수 있어야합니다. 특정 작업은 작업에서 파생 된 클래스의 객체로 정의 될 수 있습니다. 작업에 의해 실행되는 프로그램은 가상 기능으로 정의 될 수 있습니다. ... 가상 시간의 개념을 구현하는 스케줄러가 있어야합니다. ... 작업은 의사 소통해야합니다. 이를 위해 클래스 큐를 설계하십시오. ...

나는 이것이 무엇을 요구하는지 정확히 잘 모르겠습니다. 작업이 별도의 스레드입니까? (내가 아는 한, 시스템 호출없이 새 스레드를 만들 수는 없으며,이 책은 C ++에 관한 책이기 때문에 그것이 의도라고 생각하지 않습니다.) 인터럽트가 없으면 어떻게 실행을 시작하고 중지 할 수 있습니까? 기능? 나는 이것이 바쁜 대기를 포함한다고 가정합니다 (즉, 지속적으로 루프하고 조건을 확인하십시오). 시간 동안 종료되지 않을 수있는 함수에 어떻게 적용될 수 있는지 알 수는 없습니다 (예 : 무한 루프가 포함 된 경우). .

편집하다: 자세한 내용은 아래 내 게시물을 참조하십시오.

도움이 되었습니까?

해결책

힌트:u003Ctask.h> .

배송 된 오래된 협동 조합 멀티 태스킹 라이브러리에 대한 참조입니다. Cfront의 초기 버전 (해당 페이지에서 다운로드 할 수도 있습니다).

논문을 읽으면 "공동 경로 스타일 프로그래밍을위한 C ++ 클래스 세트"상황이 훨씬 더 의미가 있습니다.


조금 추가 :

나는 작업 라이브러리를 사용한 오래된 프로그래머가 아닙니다. 그러나 C ++는 Stroustrup이 Simula에 시뮬레이션을 작성한 후 작업 라이브러리와 동일한 속성을 많이 가진 시뮬레이션을 작성한 후에 설계되었다는 것을 알고 있습니다.

책에서 연습을 구현한다면 아마도 이렇게 할 것입니다 (이 코드를 테스트하지 않았거나 심지어 컴파일하려고 시도하지 않았습니다).

class Scheduler {
    std::list<*ITask> tasks;
  public:
    void run()
    {
        while (1) // or at least until some message is sent to stop running
            for (std::list<*ITask>::iterator itor = tasks.begin()
                      , std::list<*ITask>::iterator end = tasks.end()
                    ; itor != end
                    ; ++itor)
                (*itor)->run(); // yes, two dereferences
    }

    void add_task(ITask* task)
    {
        tasks.push_back(task);
    }
};

struct ITask {
    virtual ~ITask() { }
    virtual void run() = 0;
};

나는 사람들이 내 선택에 동의하지 않을 것임을 알고 있습니다. 예를 들어, 인터페이스에 구조물을 사용합니다. 그러나 Structs는 기본적으로 공개적으로 공개되는 동작 (기본적으로 클래스에서 상속이 비공개 인 경우)을 가지고 있으며 인터페이스에서 개인적으로 상속하는 값이 표시되지 않으므로 공개 상속을 기본값으로 만드는 것이 어떻습니까?

아이디어는 ITASK :: Run ()에 대한 호출이 중단 될 수있는 지점에 작업이 도착할 때까지 스케줄러를 차단하는 것입니다. 계속하다. "협력적인 멀티 태스킹"의 "협력 적"은 "작업이 중단 될 수있을 때"를 의미한다 "("코 루틴 "은 일반적으로"협력 멀티 태스킹 "을 의미한다). 간단한 작업은 run () 메소드에서 한 가지만 수행 할 수 있으며,보다 복잡한 작업은 상태 머신을 구현할 수 있으며 run () 메소드를 사용하여 현재 객체가 현재 상태를 파악하고 다른 메소드를 기반으로 호출 할 수 있습니다. 그 상태에서. 작업들 ~ 해야 하다 "협력적인 멀티 태스킹"의 정의이기 때문에 이것이 작동하기 위해 한 번에 한 번 통제력을 포기합니다. 또한 모든 현대 운영 체제가 협력 멀티 태스킹을 사용하지 않는 이유이기도합니다.

이 구현은 (1) 공정한 스케줄링을 따르지 않습니다 (Task 's Run () 메소드에 소비 된 총 시계 진드기를 유지하고 다른 작업이 "캐치 업"될 때까지 다른 작업에 비해 너무 많은 시간을 사용한 작업을 건너 뛰는 작업). , (2) 작업을 제거하거나 (3) 스케줄러를 중지 할 수 있도록 허용합니다.

작업간에 의사 소통하는 것은 계획 9의 libtask 또는 Rob Pike의 Newsqueak 영감을 얻기 위해 ( "UNIX 구현의 UNIX 구현"다운로드에는 흥미로운 가상 머신에서 전달되는 메시지를 논의하는 "Newsqueak의 구현"이 포함되어 있습니다).

그러나 나는 이것이 기본적인 골격 Stroustrup이 염두에두고 있다고 생각합니다.

다른 팁

다음은 "이벤트 중심 시뮬레이션"에 대한 이해가 있습니다.

  • 컨트롤러는 이벤트 대기열을 처리하고 특정 시간에 이벤트를 예약 한 다음 대기열에서 최고 이벤트를 실행합니다.
  • 이벤트는 예정된 시간에 즉시 OCUR입니다. 예를 들어, "이동"이벤트는 시뮬레이션에서 엔티티의 위치와 상태를 업데이트하여 상태 벡터가 현재 시뮬레이션 시간에 유효합니다. "감각"이벤트는 모든 엔티티의 상태가 현재 시간에 있는지 확인한 다음 수학적 모델을 사용하여 현재 엔터티가 다른 엔티티를 얼마나 잘 감지 할 수 있는지 평가해야합니다. (로봇이 보드에서 움직이는 것을 생각하십시오.)
  • 따라서 시간은 불연속적으로 진행되어 이벤트에서 이벤트로 점프합니다. 시간 중심의 시뮬레이션과 대조하십시오. 시간 중심의 시뮬레이션은 시간이 별도의 단계로 이동하고 모든 엔티티의 상태가 매번 단계 (LA 가장 시뮬 링크 모델)를 업데이트합니다.
  • 그런 다음 이벤트는 자연 속도로 발생할 수 있습니다. 일반적으로 시뮬레이션에서 모든 데이터를 최고의 속도로 다시 사용하는 것은 의미가 없습니다.

대부분의 프로덕션 이벤트 중심 시뮬레이션은 단일 스레드에서 실행됩니다. 그것들은 본질적으로 복잡 할 수 있으므로 멀티 스레드 시뮬레이션을 동기화하려고 시도하는 것은 지수의 복잡성 층을 추가하는 경향이 있습니다. 그렇게 말하면, 다중 프로세스 군사 시뮬레이션의 표준이 있습니다. 분산 대화식 시뮬레이션 (DIS) 사전 정의 된 TCP 메시지를 사용하여 프로세스간에 데이터를 전송합니다.

편집 : 모델링과 시뮬레이션의 차이를 정의하는 것이 중요합니다. 모델은 시스템 또는 프로세스의 수학적 표현입니다. 시뮬레이션은 일정 기간 동안 실행되는 하나 이상의 모델로 구축됩니다. 다시 말하지만, 이벤트 중심 시뮬레이션은 이벤트에서 이벤트마다 홉을, 시간 중심 시뮬레이션은 일정한 시간 단계에서 진행됩니다.

운동이 협력적인 멀티 태스킹 스케줄러를 구현하도록 요구하는 것처럼 들립니다. 스케줄러는 가상 시간에 작동합니다 (원하는 수준에서 정의/구현 시간은 시간을 표시합니다) 완료, 스케줄러는 다음을 선택하고 실행을 시작합니다.

불연속 이벤트 시뮬레이션의 일반화 된 구조는 시간 값에 키워진 우선 순위 큐를 기반으로합니다. 넓은 수준에서는 다음과 같습니다.

    While (not end condition):
        Pop next event (one with the lowest time) from the priority queue
        Process that event, which may generate more events
        If a new event is generated:
            Place this on the priority queue keyed at its generated time

공동 경로는 모델의 관점을 이벤트 중심에서 엔티티 중심으로 변경합니다. 엔터티는 일부 수명주기를 거쳐야합니다 (예 : 작업 수락, 리소스 X를 잡고, 프로세스 작업, 리소스 X를 릴리스하고, 다음 단계를 위해 큐에 작업을 배치 할 수 있습니다). Grab Resources가 세마포어와 같은 동기화 프리미티브로 처리되므로 프로그래밍하기가 다소 쉽습니다. 작업 및 동기화 프리미티브는 이벤트를 생성하고 무대 뒤에서 대기합니다.

이는 운영 체제의 프로세스와 개념적으로 유사하게 모델을 제공하고 입력 또는 요청한 공유 리소스를 사용할 때 프로세스를 깨우는 스케줄러가 제공됩니다. 공동 경로 모델을 사용하면 시뮬레이션을 훨씬 쉽게 이해할 수있어 복잡한 시스템을 시뮬레이션하는 데 유용합니다.

(나는 C ++ dev가 아닙니다)

아마도 그 의미는 주로 콜백 함수 포인터와 예약 된 시간으로 구성된 클래스 작업 (이벤트에서와 같이)을 만들어야하며 스케줄러 클래스의 목록에 저장 될 수있는 클래스 작업을 만들어야한다는 것입니다. 시간 카운터를 추적하고 시간이 도착하면 각 작업의 기능을 호출하십시오. 이러한 작업은 시뮬레이션의 객체에 의해 만들어야합니다.

개별 시뮬레이션 측면에서 도움이 필요하면 계속해서 질문을 편집하십시오.

이것은 Sottiet812의 답변에 대한 Titaniumdecoy의 의견에 반응합니다. 댓글이 너무 커서 또 다른 대답을하기로 결정했습니다.

시뮬레이션 상태는 이벤트에 대한 응답 만으로만 변경된다는 점에서 주도 된 이벤트입니다. 예를 들어, 두 가지 이벤트가 있다고 가정합니다 미사일 발사 그리고 미사일 충격. 때 시작하다 이벤트가 실행되고, 언제 어디서 영향을 미칠지 파악하고 일정을 잡습니다. 타격 적절한 시간 동안 이벤트. 미사일의 위치는 발사와 영향 사이에 계산되지 않지만 특정 시간에 위치를 얻기 위해 다른 물체가 호출 할 수있는 방법이있을 수 있습니다.

이것은 시간 구동 시뮬레이션과 대조적이며, 미사일의 정확한 위치 (및 시뮬레이션의 다른 모든 물체)가 매번 1 초 (1 초) 후에 계산됩니다.

모델의 특성에 따라 필요한 답변의 충실도 및 이벤트 중심 또는 시간 구동 시뮬레이션이 더 잘 수행 될 수 있습니다.

편집 : 누구든지 더 많은 것을 배우고 싶다면 논문을 확인하십시오. 겨울 시뮬레이션 회의

책과 프레임 워크가 있습니다 시민 (Simula의 이산 이벤트 모델링) 공동 경로 기반 프레임 워크 (시조 데모)를 설명합니다. 30 년 정도 오래된 데모에도 불구하고 실제로는 매우 좋은 시스템이며 Graham Birtwistle 정말 좋은 사람입니다.

C ++에서 공동 경로를 구현하는 경우 (SetJump/LongJump 생각) 정말 우아합니다 개별 이벤트 모델링 프레임 워크. 30 살이되었지만 시대를 초월한 클래식이며 여전히 팬 기반이 있습니다.

"me.yahoo.com/..."에 연결된 논문에서 task.h class :

  1. 작업이 병렬로 실행됩니다
  2. 작업이 중단되고 나중에 재개 될 수 있습니다

라이브러리는 멀티브로 그램 방법으로 설명됩니다.

스레드 나 별도의 프로세스를 사용하지 않고이 작업을 수행 할 수 있습니까?

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top