페이지 선택
Generic selectors
Exact matches only
Search in title
Search in content
Search in pages

세마포어(semaphore)는 멀티스레드 환경에서 스레드들이 임계영역(Critical Section)을 동시에 실행하므로서 발생할 수 있는 공유자원의 오류를 방지하기 위한 방안이다.

세마포어를 이용한 동작은 하나의 스레드가 임계영역을 실행하기 전에 세마포어라는 변수를 보고서 임계영역을 실행할 수 있는 값일 경우에만 그 코드영역을 실행한다.

 

임계영역에 대한 실행 권한을 얻은 스레드는 임계영역을 실행하기 전에 세마포어의 값을 변경해 주어 자신이 사용하고 있음을 표시하여 준 다음에 실제로 임계영역을 실행한다.

임계영역의 실행이 끝나고 나서는 세마포어 변수 값을 재 설정하여 임계영역을 실행하고자 하는 다른 스레드가 임계영역을 실행할 수 있도록 뒤 처리도 해주어야 한다.

⊕ 추가 설명은 IOT 기술 메뉴에서 ROTS 커널 부분을 참조할 수 있다.

 

♦ 공유자원

◊ 여러 스레드들이 함께 값을 읽고 쓰고 할 수 있는 변수, 메모리 영역

◊ 여러 스레드들이 함께 이용하고 제어할 수 있는 장치, ex) Timer, GPIO, 프린터

 

♦ 임계영역(critical section)

공유자원을 액세스, 즉 읽고, 쓰고, 제어하는 코드영역

 

♦ mxos 에서 사용하고 있는 세마포어는 카운팅(counting) 세마포어이다.

 

 

 

 

 

 

 

 

 

 

 

1. semaphre 데모 구현내용

코드위치 demos/os/os.c
 

 

 

define and variables
 
 
/* demo sem*/
static mos_semphr_id_t sem;
#define SEM_COUNT 10
 

 

semtx_thread

새마포어를 획득한 다음 임계영역을 실행한다.

여기서 임계영역은 단순한 예로 로그메시지를 보내는 행위이다.

세마포어를 획득 못할 경우 무한정 대기할 수 없으므로 time-out은 1초로 설정하였다.

/* demo sem*/

static mos_semphr_id_t sem;
#define SEM_COUNT 10
static void semrx_thread(void *arg)
{
    int fd;
    struct timeval t;
    fd_set rd;
    int ret;
 
    fd = mos_event_fd_new(sem);
    app_log(“event fd: %d”, fd);
    while(1) {
        t.tv_sec = 10;
        t.tv_usec = 0;
        FD_ZERO(&rd);
        FD_SET(fd, &rd);
        select(fd+1, &rd, NULL, NULL, &t);
        if (FD_ISSET(fd, &rd)) {
            ret = mos_semphr_acquire(sem, 1);
            app_log(“RX sem ret %d”, ret);
        } else {
            app_log(“RX sem timeout”);
            break;
        }
    }
 
    mos_event_fd_delete(fd);
    app_log(“semrx_thread exit”);
    mos_thread_delete(NULL);
}

 

 

semtx_thread
세마포어를 해제해준다
static void semtx_thread(void *arg)
{
    int i;
    int ret;
    for(i=0;i<20;i++) {
        ret = mos_semphr_release(sem);
        if (ret != kNoErr) {
            app_log(“put sem %d fail %d”, i, ret);
        }
    }
    mos_sleep(5);
    for(i=0;i<5;i++) {
        ret = mos_semphr_release(sem);
        if (ret != kNoErr) {
            app_log(“put sem %d fail”, i);
        }
        mos_sleep(1);
    }
    app_log(“semtx_thread exit”);
    mos_thread_delete(NULL);
}
 
 
 

 

sem_demo
static void sem_demo(void)
{
    mos_thread_id_t rt, tt;
    app_log(“sem demo start”);
    sem = mos_semphr_new(SEM_COUNT);
    rt = mos_thread_new(5, “rx”, semrx_thread, 0x500, NULL);
    tt = mos_thread_new(5, “tx”, semtx_thread, 0x500, NULL);
    mos_thread_join(rt);
    mos_thread_join(tt);
    app_log(“sem demo end”);
    mos_semphr_delete(sem);
    mos_sleep(1);
}
 

 

main

int main(void)

{
   //thread_demo();
   // timer_demo();
 
   sem_demo();
 
   //queue_demo(1);
   //queue_demo(2);
   //queue_demo(3);
   //queue_demo(4);
    return 0;
}

 

 

 

2. semaphre 데모 동작확인

♦ VSC(Visual Studio Code)의 터미널에서 semaphore 데모를 컴파일하고 Flash 다운로드→ mxos make os@emw3080 download  jtag=jlink

 

♦ EMW3080을 Reset하고 DBG 시리얼포트로 동작을 확인한 결과는 아래와 같다.

 

 

 

Adsense

EMW3070

Viewed Page List