티스토리 뷰

C언어

mutex와 크리티컬섹션 성능 차이

바람사탕 2024. 6. 15. 23:39
반응형

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와 우분투(리눅스)에서 동일한 동작을 수행합니다. 따라서 이 함수들을 사용하여 동일한 방식으로 크리티컬 섹션을 사용할 수 있습니다.

반응형
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2025/02   »
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28
글 보관함