[mbed RTOS] 2. Mutex, Semaphore, Signals

2014. 4. 13. 15:282018년 이전 관심사/mbed

반응형

Mutex


Mutex는 Thread 들의 실행의 동기화를 위해 사용 된다. 예를 들어 공유 자원(shared resource)의 동시 access를 막기 위해 사용 된다.


Mutex는 ISR(Interrupt service routines) 에서는 호출 될 수 없다.




  • Mutex()

    • mutex Object를 생성 및 초기화

  • osStatus lock(uint32_t millisec = osWaitForever)

    • mutex가 이용 가능한 상태가 될 땔  까지 기다림.

    • 다른 Thread가 mutex Lock을 해제 할 때까지 Thread를 WAITING 상태로 만든다.

  • bool trylock()

    • mutex를 이용 가능한지 즉시 Return 값으로 알 수 있다.

  • osStatus unlock()

    • 자신의 Thread가 이전에 lock 한 mutex를 해제 한다.


#include "mbed.h"

#include "rtos.h"


Serial pc(USBTX, USBRX);

Mutex stdio_mutex;


void notify(const char* name, int state)

{

    stdio_mutex.lock();

    pc.printf("%s: %d\r\n", name, state);

    stdio_mutex.unlock();

}


void test_thread(void const *args)

{

    while(true)

    {

        notify((const char*)args, 0); Thread::wait(1000);

        notify((const char*)args, 1); Thread::wait(1000);

    }

}



int main()

{

    pc.baud(115200);


    Thread t2(test_thread, (void *)"Th 2");

    Thread t3(test_thread, (void *)"Th 3");

    

    test_thread((void *)"Th 1");

}


▼ 위 코드를 컴파일해서 실행 하면, 아래와 같이 Thread가 1,2,3 순서 대로 실행 되는 것을 볼 수 있다.



Semaphore


Semaphore는 Pool 형태의 공유 자원에 access 하는 Thread들을 관리 하는데 유용하다.



  • Semaphore(int32_t count)

    • Semaphore Object 생성 및 초기화

    • 매개변수 count로  동시에 접근 할 수 있는 Thread의 개수를 설정 할 수 있음

  • int32_t wait(uint32_t millisec=osWaitForever)

    • Semaphore 자원이 이용 가능 할 때 까지 기다림

  • osStatus release(void)

    • Semaphore::wait로 획득한 Semaphore 자원을 Release 함


#include "mbed.h"

#include "rtos.h"


Semaphore two_slots(2);

Serial pc(USBTX, USBRX);


void test_thread(void const *name)

{

    while(true)

    {

        two_slots.wait();

        pc.printf("%s\r\n", (const char*)name);

        Thread::wait(1000);

        two_slots.release();        

    }

}


int main(void)

{

    pc.baud(115200);

    

    Thread t2(test_thread, (void *)"Th 2");

    Thread t3(test_thread, (void *)"Th 3");

    

    test_thread((void *)"Th 1");

}


▼ 위 코드에서 Semaphore의 Count를 2개로 설정 하였기 때문에 Thread 1,2가 거의 동시에 수행 한 후, Thread 3이 수행 된다.



Signals


각각의 Thread는 Signal을 notify 하거니 wait 할 수 있다.

  • static osEvent signal_wait(int32_t signals, uint32_t milliseco=osWaitForever)

    • 현재 RUNNING 상태의 Thread가 하나 혹은 더 많은 Signal Flag가 발생 하기를 기다림.

  • int32_t signal_set(int32_t signals)

    • 활성화된 Thread에서 Signal을 기다리고 있는 Thread에게 Signal을 알림.

#include "mbed.h"

#include "rtos.h"


Serial pc(USBTX, USBRX);


void Thread1(void const *argument)

{

    while(true)

    {

        Thread::signal_wait(0x1);

        pc.printf("Thread1\r\n");

    }

}


void Thread2(void const *argument)

{

    while(true)

    {

        Thread::signal_wait(0x2);

        pc.printf("Thread2\r\n");

    }

}



int main(void)

{

    pc.baud(115200);

    

    Thread thread1(Thread1);

    Thread thread2(Thread2);

    

    while(true)

    {

        Thread::wait(1000);

        thread1.signal_set(0x1);

        Thread::wait(1000);

        thread2.signal_set(0x2);

    }

}


▼ 위 코드를 실행하면, 아래 그림과 같이 main에서 주기적으로 Thread1과 Thread2를 깨워서 실행 한다.


[참고자료]

[mbed], http://mbed.org/handbook/RTOS




반응형