인프런 커뮤니티 질문&답변

ctk103님의 프로필 이미지
ctk103

작성한 질문수

FreeRTOS 프로그래밍

세마포어,뮤텍스 초기값 질문

해결된 질문

작성

·

374

2

안녕하세요 강의 수강 후 혼자 복습하는 중인데 세마포어 초기값 관련 이해가 가지 않는 부분이 있어 질문 드립니다.

 

1번 질문.

05_SEM 실습예제에서

sem_id = xSemaphoreCreateBinary(); -> 초기값 0?

---

loops = 10;

for(;;) {

// 세마포어 대기

if (xSemaphoreTake(sem_id, portMAX_DELAY) == pdTRUE)

{

printf("."); fflush(stdout);

}

sem_val=uxSemaphoreGetCount(sem_id);

//printf("sem_val is %d\n", (int)sem_val);

if(loops == 0)

break; // exit

loops--;

}

 

위의 경우 printf 출력되지 않고 세마포어에 의해 바로 태스크가 블럭상태에 빠집니다.

따라서 초기값은 0으로 예상됩니다.

 

07_MUTEX 실습예제에서

mutex_id = xSemaphoreCreateMutex(); -> 초기값 1?

---

int buyTicket(void)

{

/* TODO #2:

MUTEX 을 이용하여

공유변수(tickets)를 보호한다 */

#if 1

// CRITICAL SECTION(ENTER)

xSemaphoreTake(mutex_id, portMAX_DELAY);

#endif // TODO #2

tickets --; // ticket count

#if 1

// CRITICAL SECTION(EXIT)

xSemaphoreGive(mutex_id);

#endif // TODO #2

return(tickets);

}

 

위의 경우 초기값이 1이어야 해당 함수가 바로 블럭에 빠지지 않고 수행되므로 1로 예상됩니다.

영상에서는 초기값이 1로 수행된다고 이해했는데, 그렇다면 세마포어 예제에서 printf함수가 수행이 되는게 맞는데 되지 않습니다. 초기값이 서로 다르게 입력되는 것인지 궁금합니다.

 

2번 질문.

05_SEM 실습예제에서 카운트값을 디버깅하고 싶어서 보다가

#if 1

sem_id = xSemaphoreCreateBinary();

if (sem_id == NULL) printf("xSemaphoreCreateBinary error found\n");

sem_val = uxSemaphoreGetCount(sem_id);

---

loops = 10;

for(;;) {

// 세마포어 대기

if (xSemaphoreTake(sem_id, portMAX_DELAY) == pdTRUE)

{

printf("."); fflush(stdout);

}

sem_val=uxSemaphoreGetCount(sem_id);

//printf("sem_val is %d\n", (int)sem_val);

if(loops == 0)

break; // exit

loops--;

}

 

세마포어 생성 후 uxSemaphoreGetCount 함수를 호출하면 세마포어가 블럭상태에 빠지지 않고 printf함수가 출력이 됩니다. (실제 디버깅 해보면 sem_val 변수값은 0으로 찍힙니다)

위 함수에서 V연산을 하는 행위가 있는 것인가요?

 

3번 질문.

xSemaphoreCreateBinary()와 vSemaphoreCreateBinary()의 차이점이 무엇인지 궁금합니다.

 

답변 1

0

홍영기님의 프로필 이미지
홍영기
지식공유자

안녕하세요. ctk103님!

세마포어는 단순 이벤트 전달과 동시에 뮤텍스로써도 기능할 수 있는 커널 객체입니다.

2가지 기능을 가지고 있는 것으로 생각하시면 됩니다.

image

(ANS1)

xSemaphoreCreateBinary() 함수는 단순 이벤트 전달용 세마포어 생성

xSemaphoreCreateMutex() 함수는상호배제 세마포어(MUTEX) 생성 으로 이해하시면 좋겠네요.

그렇기 때문에 특별한 초기화 값을 명시하지 않아도 자동적으로 xSemaphoreCreateBinary() 함수에 의해 생성될 세마포어는 초기값을 '0' 을 갖게되고, xSemaphoreCreateMutex() 는 뮤텍스로 기능하기 위해 초기값 '1' 을 갖게되는 것입니다.

 

(ANS2)

uxSemaphoreGetCount() 함수는 단순히 현재의 세마포어 객체의 내부 저장되어 있는 세마포어 정수 값을 반환해줍니다. 따라서, 특별한 p, v 연산이 필요없습니다.

 

(ANS3)

vSemaphoreCreateBinary() 매크로는 이제 더 이상 사용되지 않습니다.(deprecated)

xSemaphoreCreateBinary() 함수가 대신 사용됩니다. 이 함수는 세마포어가 정상적으로 생성되면 세마포어의 핸들을 반환합니다.

 

ctk103님의 프로필 이미지
ctk103
질문자

답변 감사합니다.

 

세마포어는 초기값 0으로 세팅되고, 뮤텍스는 초기값 1을 가지는 것으로 이해하였습니다.

 

그런데 2번 같은 경우 uxSemaphoreGetCount() 함수 호출 시 xSemaphoreTake를 만난 후 바로 블럭 상태에 빠지지 않고 printf함수 호출하는 것을 확인했습니다.

디버깅으로 반복해서 브레이크 걸어봐도 현상은 똑같이 재현되었습니다.

왜 그런것일까요..??

홍영기님의 프로필 이미지
홍영기
지식공유자

아마도 다른 외적인 요인(이를테면 다른 태스크로부터의 깨움동작)때문에 휴면상태진입을 하지못했거나, 아니면 휴면상태진입했더라도 곧 다시 준비(ready)상태로 돌아왔겠죠.

 

코드를 아래처럼 작성해보시고(1,2,3,4 숫자는 빼고 코딩), 테스트해보세요

1번라인을 추가해서도 해보시고, 2번라인을 넣어서도 해보세요.

제가 해봤을 때는 모두 예상한대로 나옵니다.

 

image

ctk103님의 프로필 이미지
ctk103

작성한 질문수

질문하기