OS

single core에서의 multi-threading

동바리 2022. 1. 24. 09:57

 임베디드 환경에서, 특히 RTOS를 다루다보면 멀티 스레딩을 다뤄야하는 경우가 많습니다. 예전과 같이 bare-metal 구조가 아닌, 각각의 태스크들을 다뤄야하는 구조말입니다. 

 보통 ST사의 mcu를 이용해, mbed os를 다루게 됩니다. mbed os는 사실 FreeRTOS의 wrapper라고 하니, FreeRTOS를 이용하는 것과 다르지 않다고 생각합니다. 

 하지만 임베디드에 주로 이용하는 mcu의 경우 싱글 코어인 경우가 대부분이죠. 저같은 경우는 아직 멀티코어를 다뤄본경험이 없습니다. 이 mcu를 이용해 multi thread를 활용해야할 때 동기화처리에 대해서 혼란스러운 경우가 생겼었습니다. 

 우리가 보통 mutli thread를 공부할 때는 desktop을 기준으로, 멀티코어 환경을 감안합니다. 그렇기 때문에 mutex등의 활용법이 상당히 직관적입니다.

 하지만 single core인 경우는 mutex 활용법이 직관적이라고 생각되지는 않습니다. 이유로는 아래와 같습니다.

 multi core 환경에서, mutex는 여러 스레드들이 cpu 자원을 얻고 공용변수(ex 전역변수)에 동시 접근할 때 이용하게 됩니다. mutex lock unlock을 이용해 critical section을 만듭니다. 이렇게 되면 lock을 얻은 스레드만 해당 변수에 접근할 수 있기에 동기화 처리가 가능해집니다.

 하지만 single core 환경은 cpu가 1개입니다. 따라서 multi thread를 이용하더라도 특정 시점에 공용변수에 접근할 수 있는 thread는 오직 하나입니다. 이렇게 되면 single core 환경에서 mutex는 필요하지 않은것인가 생각될 수 있습니다. 왜냐면 변수에 접근할 수 있는 thread는 오직 1개뿐이니 race condition이 발생하지 않을거라고 생각할 수 있기 때문입니다.

 하지만 위는 틀린 생각입니다. 왜냐면 single core에서 race condition만 생각했지, data race는 생각하지 않았기 때문입니다. 즉 mutex를 이용하려면 두가지 경우를 모두 고려해야 한다는 이야기입니다(두 용어의 차이는 아래 링크에서 확인이 가능합니다).

 

기본 예제로 mbed os의 aws 예제를 가져와보겠습니다. 

https://github.com/ARMmbed/mbed-os-example-for-aws

 

GitHub - ARMmbed/mbed-os-example-for-aws: Mbed OS example to connect to AWS IoT Core

Mbed OS example to connect to AWS IoT Core. Contribute to ARMmbed/mbed-os-example-for-aws development by creating an account on GitHub.

github.com

32번 라인에 보면 mutex lock을 확인할 수 있습니다. 이는 주석대로 disconnect를 방지하기 위함입니다. 현재의 상태를 읽고 있는데, disconnect를 해버리면 undefined behavior가 되겠죠. client라는 resource에 data race가 발생하기 때문에 mutex를 했습니다. A스레드가 37번 라인의 isConnect() function을 수행하는 도중 블로킹 function이 있다면, B 스레드에게 cpu가 넘어갈 수도 있고, B 스레드는 disconnect() function을 수행하는 함수라고 한다면, 위와 같은 문제가 발생할 수 있습니다. 

 결론은 single core이더라도 mutex가 필요한 경우도 있고, 이를 행하기 위해서는 multi thread에서 발생하는 문제에 대한 정확한 인식이 필요합니다.

 

 

 

 

출처 : https://www.youtube.com/watch?v=0pvx4k0lsoA