2016-12-21 1 views
0

David E.Simon이 "Embedded Software Primer"를 읽습니다. RTOS와 그 빌딩 블록 Scheduler and Task에 대해 설명합니다. 각 작업은 준비 상태, 실행 중 상태 또는 차단 상태 중 하나입니다. 제 질문은 스케줄러가 작업이 차단 상태에 있다고 판단하는 방법입니다. 그것은 세마포를 기다리고 있다고 가정합니다. 그렇다면 Semaphore는 반환 할 수없는 상태에 놓인 것 같습니다. Scheduler는 함수가 반환하지 않는지 확인한 다음 상태를 Blocking으로 표시합니까?스케줄러가 작업이 차단 상태임을 어떻게 알 수 있습니까?

+0

세마포 및 while 루프? Thos는 동기화 primitive를 기다리는 특별한 방법입니다 ... –

+0

Semaphore의 구현은 while() 루프입니다. 나는 그 질문을 편집 할 것이다. –

+2

당신이 묻는 것은 실제로 RTOS가 일반적으로 어떻게 작동하는지에 대한 실질적인 관심이없는 구현 세부 사항입니다. 이를 구현할 수있는 몇 가지 방법이 있으며 선택은 코드 크기 제한, 사용 가능한 RAM (예 : 매우 작은 마이크로), 전체 성능 등에 따라 달라질 수 있습니다. 예를 들어 주어진 세마포어를 사용할 수없는 경우 작업이 차단으로 표시됩니다 그것을 얻기 위해. 또는 세마포어를 사용할 수없는 경우 다음 작업으로 넘어 가서 (암시 적으로 차단 된 것으로 표시) 다음 작업 조각에서 세마포를 사용할 수있게 될 때까지 다시 시도하십시오 (가난한 사람의 버전). – tonypdmtr

답변

1

구현 세부 사항은 RTOS에 따라 달라집니다. 일반적으로 각 작업에는 작업 준비, 실행 또는 차단 여부를 식별하는 상태 변수가 있습니다. 스케줄러는 작업의 상태 변수를 읽어 작업이 차단되었는지 여부를 결정합니다.

각 작업에는 작업의 상태와 컨텍스트를 결정하는 일련의 매개 변수가 있습니다. 이러한 매개 변수는 종종 구조체에 저장되며 "작업 제어 블록"이라고합니다 (구현은 RTOS에 따라 다릅니다). 준비/실행/블록 상태 변수는 작업 제어 블록의 일부일 수 있습니다.

작업이 세마포어를 가져 오려고 시도하고 세마포를 사용할 수 없으면 작업이 차단 된 상태로 설정됩니다. 보다 구체적으로, semaphore-get 함수는 작업을 실행에서 차단으로 변경합니다. 그런 다음 스케줄러가 호출되어 다음에 실행할 작업을 결정합니다. 스케줄러는 타스크 상태 변수를 읽고 블록 된 타스크를 실행하지 않습니다.

다른 작업이 결국 세마포어를 설정하면 세마포어에서 차단 된 작업이 차단됨에서 준비 됨 상태로 변경되고 컨텍스트 전환이 발생하는지 확인하기 위해 스케줄러가 호출 될 수 있습니다. . 나는 RTOS (http://distortos.org/)을 쓰고 있어요으로

1

, 나는

실제로 보통의 RTOS에 구현되어 각 스레드의 상태를 유지 변수 내가 차임 수 있다는 생각이 내에게 버전이 포함되어 있습니다 : https://github.com/DISTORTEC/distortos/blob/master/include/distortos/ThreadState.hpp#L26 https://github.com/DISTORTEC/distortos/blob/master/include/distortos/internal/scheduler/ThreadControlBlock.hpp#L329

그러나이 변수는 일반적으로 디버깅 지원이나 추가 검사 (이미 시작된 스레드 시작 방지)에서만 사용됩니다.

딥 임베디드 시스템을 목표로하는 RTOS에서 준비/차단 여부는 일반적으로 스레드를 보관하는 컨테이너를 사용하여 구분됩니다. 일반적으로 스레드는 링크 된 목록에서 "연결"되며 대개 우선 순위와 삽입 시간으로 정렬됩니다. 스케줄러에는 "ready"(https://github.com/DISTORTEC/distortos/blob/master/include/distortos/internal/scheduler/Scheduler.hpp#L340) 스레드 목록이 있습니다. 각 동기화 객체 (세마포어와 같은)에는이 객체를 기다리는 "차단 된"스레드 목록이 있습니다 (https://github.com/DISTORTEC/distortos/blob/master/include/distortos/Semaphore.hpp#L244). 스레드가 현재 사용할 수없는 세마포어를 사용하려고하면 단순히 스케줄러의 "준비 됨"목록에서 세마포어의 "차단됨"목록 (https://github.com/DISTORTEC/distortos/blob/master/source/synchronization/Semaphore.cpp#L82)으로 이동됩니다. 스케줄러는 아무 것도 결정할 필요가 없습니다. 스케줄러의 관점에서 보면이 스레드는 이제 막 사라졌습니다. 이 세마포어가 다른 스레드에 의해 해제 될 때,이 세마포어의 "차단"목록에서 기다리고 있던 첫 번째 스레드는 다시 스케줄러의 "준비"목록 (https://github.com/DISTORTEC/distortos/blob/master/source/synchronization/Semaphore.cpp#L39)으로 이동합니다.

일반적으로 준비된 스레드와 실제로 실행중인 스레드는 특별한 구분을 할 필요가 없습니다. 실제로 실행할 수있는 스레드의 양이 고정되어 있으며 사용 가능한 CPU 코어 수와 같으면 각 코어에서 실행중인 "준비"목록의 스레드를 가리키는 각 CPU 코어에 대한 포인터 만 있으면됩니다. 그 순간. 내 시스템에서 나는 똑같은 일을한다. "ready"목록의 맨 위에있는 스레드는 실행 중이지만 그 스레드 (https://github.com/DISTORTEC/distortos/blob/master/include/distortos/internal/scheduler/Scheduler.hpp#L337)를 가리키는 반복자도 관리한다.스레드를 실행하기위한 별도의 목록을 만들 수도 있지만 대부분의 경우 공간이 낭비되고 (보통 하나만 존재) 다른 것들은 약간 더 복잡해집니다.

관심이 있다면 실제로 스레드 상태와 전환에 관한 기사를 작성했습니다 - http://distortos.org/documentation/task-states/이 기사는 "준비"스레드와 실제로 실행중인 스레드 사이에 특별한 구별이 없습니다. 나는 "준비"스레드 중 어느 것이 실행 중인지를 알 수있는 다른 방법이있는 한이 구분을 실제로 유용하게 생각하지 않습니다.

관련 문제