티스토리 뷰
Mutex와 크리티컬 섹션은 모두 동기화 기법으로서, 여러 스레드가 공유 자원에 안전하게 접근할 수 있도록 도와줍니다. 그러나 이 두 가지 접근 방식 간에는 성능상의 차이가 있습니다.
1. Mutex:
- 동작 방식: Mutex는 잠금 메커니즘을 사용하여 공유 자원에 대한 접근을 제어합니다. 스레드는 mutex를 획득하기 위해 경합하고, mutex를 사용하는 스레드가 해당 자원을 사용 중이면 다른 스레드는 대기해야 합니다.
- 성능: 일반적으로 Mutex는 더 많은 오버헤드를 가지고 있습니다. Mutex의 획득과 해제에는 시스템 호출이 필요하며, 이로 인해 더 많은 오버헤드가 발생합니다. 또한, Mutex는 운영 체제에서 지원하는 여러 기능을 제공하기 때문에 크기가 더 큰 객체입니다.
2. 크리티컬 섹션:
- 동작 방식: 크리티컬 섹션은 특정 코드 영역을 지정하여 한 번에 하나의 스레드만이 해당 코드를 실행할 수 있도록 합니다. 다른 스레드는 크리티컬 섹션에 진입하기 위해 경합하며, 진입한 스레드가 섹션을 빠져나가야만 다른 스레드가 접근할 수 있습니다.
- 성능: 크리티컬 섹션은 Mutex보다 더 경량화되어 있습니다. 대부분의 경우, 크리티컬 섹션은 프로세스 내부에서 동작하며, 시스템 호출이 필요하지 않습니다. 따라서 오버헤드가 작아 성능이 더 좋을 수 있습니다. 그러나 일부 운영 체제에서는 크리티컬 섹션이 조금 더 제한적일 수 있습니다.
일반적으로 소규모의 임계 영역이 있을 때는 크리티컬 섹션을 사용하는 것이 더 효율적일 수 있으며, 복잡한 동기화 기능이 필요할 때는 Mutex를 사용하는 것이 더 적합합니다. 그러나 실제 성능은 사용하는 운영 체제, 하드웨어, 그리고 애플리케이션의 특성에 따라 다를 수 있습니다.
크리티컬섹션 win32 c 예제
#include <windows.h> #include <stdio.h> // 전역 변수로 크리티컬 섹션을 선언합니다. CRITICAL_SECTION g_cs; // 스레드 함수 DWORD WINAPI MyThreadFunction(LPVOID lpParam) { // 크리티컬 섹션 진입 EnterCriticalSection(&g_cs); // 공유 자원에 대한 작업 수행 printf("Thread %d is using shared resource.\n", GetCurrentThreadId()); // 크리티컬 섹션 빠져나옴 LeaveCriticalSection(&g_cs); return 0; } int main() { // 크리티컬 섹션 초기화 InitializeCriticalSection(&g_cs); // 스레드 생성 HANDLE hThread1 = CreateThread(NULL, 0, MyThreadFunction, NULL, 0, NULL); HANDLE hThread2 = CreateThread(NULL, 0, MyThreadFunction, NULL, 0, NULL); // 스레드 종료 대기 WaitForSingleObject(hThread1, INFINITE); WaitForSingleObject(hThread2, INFINITE); // 크리티컬 섹션 삭제 DeleteCriticalSection(&g_cs); return 0; } |
이 예제는 두 개의 스레드가 공유 자원에 대해 안전하게 접근할 수 있도록 크리티컬 섹션을 사용하는 방법을 보여줍니다. InitializeCriticalSection 함수로 크리티컬 섹션을 초기화하고, EnterCriticalSection 함수로 섹션에 진입한 후 공유 자원에 대한 작업을 수행합니다. 작업이 끝나면 LeaveCriticalSection 함수로 섹션을 빠져나옵니다. 이렇게 함으로써 한 번에 하나의 스레드만이 공유 자원을 사용할 수 있습니다.
크리티컬섹션 우분투 c 예제
우분투나 다른 리눅스 시스템에서는 크리티컬 섹션을 직접적으로 제공하지 않습니다. 대신, POSIX 스레드를 사용하여 스레드 간 동기화를 구현할 수 있습니다. POSIX 스레드에서는 뮤텍스(mutex)를 사용하여 크리티컬 섹션과 비슷한 동작을 구현할 수 있습니다. 아래는 우분투에서 뮤텍스를 사용하여 크리티컬 섹션과 같은 동작을 하는 간단한 C 예제입니다.
#include #include // 전역 변수로 뮤텍스를 선언합니다. pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; // 스레드 함수 void* myThreadFunction(void* arg) { // 뮤텍스 락 pthread_mutex_lock(&mutex); // 공유 자원에 대한 작업 수행 printf("Thread %ld is using shared resource.\n", pthread_self()); // 뮤텍스 언락 pthread_mutex_unlock(&mutex); return NULL; } int main() { // 뮤텍스 초기화 pthread_mutex_init(&mutex, NULL); // 스레드 생성 pthread_t thread1, thread2; pthread_create(&thread1, NULL, myThreadFunction, NULL); pthread_create(&thread2, NULL, myThreadFunction, NULL); // 스레드 종료 대기 pthread_join(thread1, NULL); pthread_join(thread2, NULL); // 뮤텍스 해제 pthread_mutex_destroy(&mutex); return 0; } |
이 예제는 두 개의 스레드가 공유 자원에 대해 안전하게 접근할 수 있도록 뮤텍스를 사용하는 방법을 보여줍니다. 'pthread_mutex_lock' 함수로 뮤텍스를 락하고, 공유 자원에 대한 작업을 수행한 후 'pthread_mutex_unlock' 함수로 뮤텍스를 언락합니다. 이렇게 함으로써 한 번에 하나의 스레드만이 공유 자원을 사용할 수 있습니다.
win32와 우분투에서 동일하게 사용할 수 있는 크리티컬섹션 함수
아래는 Win32와 우분투(리눅스)에서 동일하게 사용할 수 있는 크리티컬 섹션 함수를 구현한 예제입니다.
#ifdef _WIN32 #include <windows.h> #else #include <pthread.h> #endif // 크리티컬 섹션 구조체 정의 typedef struct { #ifdef _WIN32 CRITICAL_SECTION cs; #else pthread_mutex_t mutex; #endif } CriticalSection; // 크리티컬 섹션 초기화 함수 void InitializeCriticalSection(CriticalSection* cs) { #ifdef _WIN32 InitializeCriticalSection(&cs->cs); #else pthread_mutex_init(&cs->mutex, NULL); #endif } // 크리티컬 섹션 진입 함수 void EnterCriticalSection(CriticalSection* cs) { #ifdef _WIN32 EnterCriticalSection(&cs->cs); #else pthread_mutex_lock(&cs->mutex); #endif } // 크리티컬 섹션 빠져나오는 함수 void LeaveCriticalSection(CriticalSection* cs) { #ifdef _WIN32 LeaveCriticalSection(&cs->cs); #else pthread_mutex_unlock(&cs->mutex); #endif } // 크리티컬 섹션 삭제 함수 void DeleteCriticalSection(CriticalSection* cs) { #ifdef _WIN32 DeleteCriticalSection(&cs->cs); #else pthread_mutex_destroy(&cs->mutex); #endif } // 테스트를 위한 함수 void* myThreadFunction(void* arg) { CriticalSection* cs = (CriticalSection*)arg; EnterCriticalSection(cs); printf("Thread %ld is using critical section.\n", pthread_self()); LeaveCriticalSection(cs); return NULL; } int main() { CriticalSection cs; InitializeCriticalSection(&cs); pthread_t thread1, thread2; pthread_create(&thread1, NULL, myThreadFunction, &cs); pthread_create(&thread2, NULL, myThreadFunction, &cs); pthread_join(thread1, NULL); pthread_join(thread2, NULL); DeleteCriticalSection(&cs); return 0; } |
이 코드는 `CriticalSection` 구조체를 정의하고, 해당 구조체를 사용하여 크리티컬 섹션을 관리하는 함수를 구현했습니다. `InitializeCriticalSection`, `EnterCriticalSection`, `LeaveCriticalSection`, `DeleteCriticalSection` 함수는 Win32와 우분투(리눅스)에서 동일한 동작을 수행합니다. 따라서 이 함수들을 사용하여 동일한 방식으로 크리티컬 섹션을 사용할 수 있습니다.
'C언어' 카테고리의 다른 글
작성중 - MonitorBrightness (0) | 2024.06.19 |
---|---|
mfcs42.pdb (0) | 2024.06.15 |
남이 짠 소스코드 분석하기 (1) | 2024.06.11 |
protocol buffer (0) | 2024.05.29 |
우분투와 윈도우에서 동시에 동작되는 c언어 소스코드를 작성하는 방법 (1) | 2024.05.14 |