현생/TCP 소켓 프로그래밍

18-3. 쓰레드의 임계영역, 동기화 [C][LINUX]

푸더기 2022. 2. 16. 23:29
반응형

 

둘 이상의 쓰레드를 생성할 때, 둘 이상의 쓰레드가 동시에 호출하면 문제를 일으키는 문장의 영역을 임계영역이라 합니다.

따라서 함수는 임계영역과 관련해서 두 종류로 나뉘어집니다.

쓰레드에 안전한 함수(Thread-safe Function)
쓰레드에 불안전한 함수(Thread-unsafe Function)

쓰레드에 안전한 함수에도 임계영역이 있을 수 있는데, 둘 이상의 쓰레드가 동시에 접근해도 문제를 일으키지 않도록 적절한 조치가 이뤄졌기에 안전한 것입니다. 다행히 기본적으로 제공되는 대부분의 표준함수는 쓰레드에 안전하고, 쓰레드에 불안전한 함수는 안전한 형태로 재 구현된 함수가 존재하며 쓰레드와 안전한 함수와 불안전한 함수의 구분을 직접할 필요는 없습니다.

헤더파일 선언 이전에 매크로 _REENTRANT 를 정의하면 자동으로 쓰레드에 안전한 함수를 호출할 수 있고, #define 문장을 추가하지 않고 컴파일 시 -D_REENTRANT 옵션을 추가하면 됩니다.

 

임계영역이 생기는 원인은 하나의 변수에 둘 이상의 쓰레드가 동시에 접근할 때 생깁니다. 어떠한 메모리 공간이든 동시에 접근 하면 문제가 발생하는데, 100의 값을 가진 q라는 전역변수가 있을 때 A쓰레드에서는 1을 증가시키고 B쓰레드에서는 1을 감소시킨다고 가정합니다. 이상적으로는 1이 증가하고 1이 감소해서 100으로 되돌아와야 하지만, 값을 증감시킬 때에는 먼저 CPU에 값을 보내고 연산이 완료되면 변수에 저장하게 되는데, A쓰레드와 B쓰레드가 동시에 CPU에 값을 보내면 당연하게도 문제가 생길 것입니다.

 

따라서 한 쓰레드가 메모리에 접근해서 계산을 완료할 때까지 다른 쓰레드가 해당 메모리에 접근하지 못하도록 막아야하고, 이 과정을 동기화(Synchronization)이라 부릅니다.

 

동기화 기법은 대표적으로 두 가지가 있는데, 뮤텍스와 세마포어가 있습니다. 뮤텍스는 18-4, 세마포어는 18-5에서 다루겠습니다.

반응형