임계 구역(critical section)은 여러 태스크나 인터럽트 처리기가 함께 쓰는 자원에 접근하는 코드 구간이다. 공유 자원에는 전역 변수, 메모리 버퍼와 자료 구조 같은 메모리 위의 자료와, 주변 장치와 그 레지스터가 있다.[1][2] 파일도 한 번에 한 스레드만 쓰도록 보호해야 하는 공유 자원이다.[3][4] 한 실행 흐름이 공유 자원에 접근하는 동안 다른 흐름은 그 자원에 접근하지 못하게 해, 접근을 한 번에 하나로 줄 세우는 것을 상호 배제(mutual exclusion)라 한다.[2][5]

Dijkstra는 EWD123(Cooperating Sequential Processes)에서 임계 구역을 가진 N개 프로세스 가운데 언제나 많아야 하나만 임계 구역에 있게 하는 상호 배제 문제를 다루고, 세마포어를 써서 풀었다.[6]

끊길 수 있는 접근

FreeRTOS 커널 책에 따르면 PORTA |= 0x01 같은 C 문장은 보통 값을 레지스터로 읽고, 레지스터에서 고치고, 메모리에 다시 쓰는 여러 명령(read-modify-write)으로 번역되어 중간에 끊길 수 있다. 변수를 고칠 때도 같다. 한 태스크가 값을 읽은 뒤 고쳐 쓰기 전에 선점되고 그사이 다른 태스크가 같은 값을 고치면, 앞 태스크가 돌아와 옛 값을 고쳐 써서 다른 태스크의 수정을 덮어쓴다.[2]

이처럼 실행 결과가 여러 실행 흐름의 상대적인 실행 시점이나 순서에 따라 달라지는 것을 race condition이라 한다.[7][8]

POSIX.1-2024는 서로 다른 스레드의 충돌하는 두 동작 가운데 적어도 하나가 원자적이지 않고 어느 쪽도 다른 쪽보다 먼저 일어나지 않는 상황을 데이터 경쟁(data race)으로 정의하고, 데이터 경쟁이 있으면 동작이 정의되지 않는다고 정한다.[5][9] 데이터 경쟁을 피하도록, 둘 이상의 스레드나 프로세스가 lock-free가 아닌 방식으로 같은 메모리 위치에 접근할 때 한쪽이 고치는 동안 다른 쪽이 그 위치를 읽거나 고치지 못하게 하는 일을 애플리케이션에 요구한다. 또 pthread_mutex_lock, pthread_mutex_unlock 같은 함수가 뮤텍스를 얻거나 놓을 때 메모리를 동기화한다고 정한다. 메모리를 동기화하는 함수에는 세마포어의 sem_wait, sem_post와 스핀락의 pthread_spin_lock, pthread_spin_unlock도 든다.[9]

인터럽트 금지

임계 구역 동안 인터럽트를 모두 끄면 그 구간은 인터럽트에 끊기지 않는다.[1][10] FreeRTOS에서는 선점형 context switch가 인터럽트 안에서만 일어나므로, taskENTER_CRITICAL()로 인터럽트를 끈 태스크는 임계 구역을 나올 때까지 실행 상태에 머문다. 다만 포트가 configMAX_SYSCALL_INTERRUPT_PRIORITY를 쓰면 그 우선순위 이하의 인터럽트만 꺼지고, 더 높은 인터럽트는 켜진 채 남는다.[11]

AUTOSAR R25-11 OS 명세는 인터럽트 금지가 그것을 호출한 코어에만 걸리게 정한다. 그래서 다른 코어에서는 스케줄링과 인터럽트 처리가 계속된다.[12] Zephyr와 RTEMS(Real-Time Executive for Multiprocessor Systems) 문서에 따르면 SMP(Symmetric Multiprocessing) 시스템에서 한 프로세서의 인터럽트를 가려도 다른 프로세서가 같은 데이터에 동시에 접근하는 것은 막지 못하므로, 인터럽트 금지만으로는 시스템 전체의 상호 배제가 되지 않는다.[13][14] PREEMPT_RT 커널에서는 spinlock_t를 잡는 spin_lock_irq 같은 _irq 접미사 함수도 인터럽트를 끄지 않는다.[15]

인터럽트를 끄는 임계 구역은 짧게 둔다.[1][11] 인터럽트를 끄는 임계 구역이 길면 인터럽트 응답 시간이 나빠진다.[11][16]

스케줄러 잠금

스케줄러 잠금은 임계 구역 동안 태스크 전환을 막는다.[17][18] µC/OS-III와 FreeRTOS에서는 스케줄러를 잠근 동안에도 인터럽트를 받아 처리한다.[17][19] FreeRTOS에 따르면 인터럽트를 끄기에는 너무 긴 임계 구역은 스케줄러를 멈춰 만들 수 있다.[2] OSEK OS에서는 태스크가 resource의 하나인 RES_SCHEDULER를 얻어 스케줄러를 잠근다.[1]

µC/OS-III와 FreeRTOS에서는 태스크와 인터럽트 처리기가 함께 쓰는 임계 구역은 인터럽트를 꺼서 보호하고, 태스크끼리만 쓰는 임계 구역은 스케줄러를 잠가 보호할 수 있다.[2][20] FreeRTOS에서 스케줄러를 멈춘 동안 인터럽트가 요청한 context switch는 보류되었다가 스케줄러를 다시 켤 때 일어난다. 커널이 중첩 깊이를 세므로 멈추기와 다시 켜기는 중첩해 부를 수 있고, 깊이가 0으로 돌아와야 스케줄러가 다시 켜진다.[2] µC/OS-III에서도 스케줄러를 잠근 동안 인터럽트가 더 높은 우선순위 태스크를 준비시키면 커널은 인터럽트된 태스크로 돌아가고, 잠금을 푼 뒤 context switch를 한다. 잠금은 중첩할 수 있고, 잠근 횟수만큼 풀어야 스케줄러가 다시 돈다.[21]

CMSIS-RTOS2는 osKernelLock으로 모든 태스크 전환을 잠그고 그 전의 잠금 상태를 돌려주게 하며, osKernelRestoreLock으로 그 상태를 되돌리게 한다. osKernelLock은 ISR(Interrupt Service Routine)에서 부를 수 없다.[18]

RTEMS의 단일 프로세서 구성에서는 스레드의 선점을 꺼서 스레드 사이의 상호 배제를 보장할 수 있지만, SMP 구성에서는 실행 중인 스레드가 여럿일 수 있어 그럴 수 없다. 그래서 RTEMS는 SMP 구성에서 이 기능을 막는다.[22]

µC/OS-III 문서는 상호 배제 방법마다 쓸 때를 아래처럼 제시한다.[23]

방법쓸 때
인터럽트 금지공유 자원 접근이 µC/OS-III의 인터럽트 금지 시간보다 짧을 때. 문서는 쓰지 않기를 권한다.
스케줄러 잠금접근이 인터럽트 금지 시간보다 길되 스케줄러 잠금 시간보다 짧을 때. 문서는 쓰지 않기를 권한다.
세마포어자원을 함께 쓰는 태스크에 모두 마감 시한이 없을 때
뮤텍스문서가 가장 나은 방법으로 보는 것. 특히 마감 시한이 있는 태스크가 함께 쓰는 자원에 권한다.

락

락은 공유 자원마다 하나씩 두고, 자원에 접근하기 전에 잡고 다 쓴 뒤 푼다.[2][24] 락이 이미 잡혀 있을 때 뮤텍스는 잡으려는 쪽을 뮤텍스를 쓸 수 있게 될 때까지 블록시키고[25][26], 스핀락은 락이 풀릴 때까지 루프를 돌며 되풀이해 검사한다.[12][27]

락으로 상호 배제를 이루면 교착 상태와 우선순위 역전이 생길 수 있다.[1][2]

우선순위 상한

OSEK/VDX OS 2.2.3 명세는 resource를 얻은 태스크의 우선순위를 미리 정한 상한까지 올리게 해, 같은 resource를 쓰는 다른 태스크가 그동안 실행되지 못하게 한다.[1] 규칙은 ceiling priority, 일반형은 우선순위 상한 프로토콜에서 다룬다.

AUTOSAR R25-11 OS 명세는 이 상호 배제를 같은 코어의 태스크 사이로 한정한다.[12]

[1]
“OSEK/VDX Operating System Specification, Version 2.2.3,” OSEK/VDX, 2005. Accessed: Sep. 30, 2026. [Online]. Available: https://web.archive.org/web/20060219185811/http://osek-vdx.org/mirror/os223.pdf
[2]
“Mastering the FreeRTOS Real Time Kernel: A Hands-On Tutorial Guide, Chapter 8: Resource Management,” FreeRTOS (Amazon Web Services), 2026. Accessed: Sep. 30, 2026. [Online]. Available: https://github.com/FreeRTOS/FreeRTOS-Kernel-Book/blob/main/ch08.md
[3]
“Reentrant Function (Multithreaded Programming Guide),” Oracle, 2010. Accessed: Sep. 30, 2026. [Online]. Available: https://docs.oracle.com/cd/E19253-01/816-5137/guide-3/index.html
[4]
“CMSIS-RTOS2: Mutex Management,” Arm Limited, 2026. Accessed: Sep. 30, 2026. [Online]. Available: https://arm-software.github.io/CMSIS_6/latest/RTOS2/group__CMSIS__RTOS__MutexMgmt.html
[5]
“Definitions, Base Definitions (The Open Group Base Specifications Issue 8, IEEE Std 1003.1-2024),” 2024. Accessed: Sep. 30, 2026. [Online]. Available: https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/V1_chap03.html
[6]
E. W. Dijkstra, “Cooperating Sequential Processes (EWD123).” 1965. Accessed: Oct. 07, 2026. [Online]. Available: https://www.cs.utexas.edu/~EWD/transcriptions/EWD01xx/EWD123.html
[7]
“Unreliable Guide To Locking (The Linux Kernel documentation),” The Linux Kernel development community, 2026. Accessed: Sep. 30, 2026. [Online]. Available: https://docs.kernel.org/kernel-hacking/locking.html
[8]
“Managed Threading Best Practices (.NET),” Microsoft, 2026. Accessed: Sep. 30, 2026. [Online]. Available: https://learn.microsoft.com/en-us/dotnet/standard/threading/managed-threading-best-practices
[9]
“General Concepts, Base Definitions (The Open Group Base Specifications Issue 8, IEEE Std 1003.1-2024),” 2024. Accessed: Sep. 30, 2026. [Online]. Available: https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/V1_chap04.html
[10]
“MPLAB Harmony Integrated Software Framework: OSAL Libraries Help (MPLAB Harmony v2.06),” Microchip Technology Inc., 2018. Accessed: Sep. 30, 2026. [Online]. Available: https://ww1.microchip.com/downloads/aemDocuments/documents/OTH/ProductDocuments/UserGuides/MPLABHarmonyOSALLibrariesHelpv2.06.pdf
[11]
“taskENTER_CRITICAL(), taskEXIT_CRITICAL(),” FreeRTOS (Amazon Web Services), 2026. Accessed: Sep. 30, 2026. [Online]. Available: https://www.freertos.org/Documentation/02-Kernel/04-API-references/04-RTOS-kernel-control/01-taskENTER_CRITICAL_taskEXIT_CRITICAL
[12]
“Specification of Operating System (AUTOSAR CP R25-11),” AUTOSAR, 2025. Accessed: Sep. 30, 2026. [Online]. Available: https://www.autosar.org/fileadmin/standards/R25-11/CP/AUTOSAR_CP_SWS_OS.pdf
[13]
“Symmetric Multiprocessing (Zephyr Project Documentation),” Zephyr Project, 2026. Accessed: Oct. 07, 2026. [Online]. Available: https://docs.zephyrproject.org/latest/kernel/services/smp/smp.html
[14]
“30.3.4. Disabling of Interrupts, Symmetric Multiprocessing (SMP) (RTEMS Classic API Guide 6.2),” RTEMS Project, 2025. Accessed: Oct. 07, 2026. [Online]. Available: https://docs.rtems.org/docs/6.2/c-user/symmetric_multiprocessing_services.html#disabling-of-interrupts
[15]
“Lock types and their rules (The Linux Kernel documentation),” The Linux Kernel development community, 2026. Accessed: Sep. 30, 2026. [Online]. Available: https://docs.kernel.org/locking/locktypes.html
[16]
“Real-Time Systems Concepts (µC/OS-II Documentation),” Micrium (Silicon Labs), 2026. Accessed: Sep. 29, 2026. [Online]. Available: https://micrium.atlassian.net/wiki/spaces/osiidoc/pages/163855/Real-Time+Systems+Concepts
[17]
“Locking the Scheduler (µC/OS-III Documentation),” Micrium (Silicon Labs), 2026. Accessed: Oct. 07, 2026. [Online]. Available: https://micrium.atlassian.net/wiki/spaces/osiiidoc/pages/131432
[18]
“CMSIS-RTOS2: Kernel Information and Control,” Arm Limited, 2026. Accessed: Oct. 07, 2026. [Online]. Available: https://arm-software.github.io/CMSIS_6/latest/RTOS2/group__CMSIS__RTOS__KernelCtrl.html
[19]
“vTaskSuspendAll(),” FreeRTOS (Amazon Web Services), 2026. Accessed: Sep. 30, 2026. [Online]. Available: https://www.freertos.org/Documentation/02-Kernel/04-API-references/04-RTOS-kernel-control/05-vTaskSuspendAll
[20]
“Critical Sections (µC/OS-III Documentation),” Micrium (Silicon Labs), 2026. Accessed: Oct. 07, 2026. [Online]. Available: https://micrium.atlassian.net/wiki/spaces/osiiidoc/pages/131433
[21]
“Lock-Unlock (µC/OS-III Documentation),” Micrium (Silicon Labs), 2026. Accessed: Oct. 07, 2026. [Online]. Available: https://micrium.atlassian.net/wiki/spaces/osiiidoc/pages/131442
[22]
“30.3.3. Disabling of Thread Preemption, Symmetric Multiprocessing (SMP) (RTEMS Classic API Guide 6.2),” RTEMS Project, 2025. Accessed: Oct. 07, 2026. [Online]. Available: https://docs.rtems.org/docs/6.2/c-user/symmetric_multiprocessing_services.html#disabling-of-thread-preemption
[23]
“Resource Management (µC/OS-III Documentation),” Micrium (Silicon Labs), 2026. Accessed: Oct. 07, 2026. [Online]. Available: https://micrium.atlassian.net/wiki/spaces/osiiidoc/pages/131388
[24]
“ARMv8-A Synchronization primitives (ARM 100934_0100_00_en),” Arm Limited, 2017. Accessed: Sep. 30, 2026. [Online]. Available: https://documentation-service.arm.com/static/5efa1989dbdee951c1ccdea1
[25]
“pthread_mutex_lock, pthread_mutex_trylock, pthread_mutex_unlock — lock and unlock a mutex (The Open Group Base Specifications Issue 8, IEEE Std 1003.1-2024),” 2024. Accessed: Sep. 30, 2026. [Online]. Available: https://pubs.opengroup.org/onlinepubs/9799919799/functions/pthread_mutex_lock.html
[26]
“Mutexes,” FreeRTOS (Amazon Web Services), 2026. Accessed: Sep. 30, 2026. [Online]. Available: https://www.freertos.org/Documentation/02-Kernel/02-Kernel-features/02-Queues-mutexes-and-semaphores/04-Mutexes
[27]
“pthread_spin_lock, pthread_spin_trylock — lock a spin lock object (The Open Group Base Specifications Issue 8, IEEE Std 1003.1-2024),” 2024. Accessed: Sep. 30, 2026. [Online]. Available: https://pubs.opengroup.org/onlinepubs/9799919799/functions/pthread_spin_lock.html