[CSAPP 12장 골라읽기] 12.3 스레드를 이용한 동시성 프로그래밍 빠삭하게 이해하기

2025. 5. 5. 22:47·크래프톤 정글/컴퓨터구조(CSAPP)

스레드를 이용한 동시성 프로그래밍 빠삭하게 이해하기

이제 기존의 웹 서버를 하나의 요청만 처리하던 반복적 서버에서, 동시에 여러 클라이언트를 처리할 수 있는 동시성 서버로 발전시켜나갈 시점인데요. 그 핵심 열쇠 중 하나가 바로 스레드입니다.

 

 

프로세스 vs 스레드

  • 프로세스: 프로그램의 독립된 실행 단위. 각각의 주소 공간을 가진다
  • 스레드: 하나의 프로세스 안에서 실행되는 작업 단위. 스레드 간 메모리를 공유한다

스레드의 장점

  • 같은 메모리 공간에서 통신하므로 빠르고 가볍다
  • 문맥 전환(context switch) 비용 감소

스레드의 단점

  • 공유된 공간으로 인해 경쟁 조건(race condition)이 발생할 위험이 커진다.

 

pthread로 스레드 다루기, 핵심 API 세트

pthread_create(&tid, NULL, thread_func, arg);
pthread_exit(NULL);
pthread_join(tid, &retval);
  • pthread_create: 새로운 스레드 생성. thread_func을 실행
  • pthread_exit: 스레드 종료
  • pthread_join: 다른 스레드가 끝날 때까지 기다림 (동기화용)

메인 스레드가 너무 빨리 끝나면, 자식 스레드가 실행도 못하고 죽을 수 있으므로 주의해야 합니다.

 

 

Race Condition(경쟁 조건)

여러 스레드가 동시에 하나의 공유 자원에 접근 및 수정하려 할 때, 실행 순서에 따라 결과가 달라지는 상황을 경쟁 조건이라고 합니다.

// 두 스레드가 동시에 실행 중이라고 가정
cnt++;  // cnt는 전역 변수

이때, 실행 순서에 따라 실제로는 1만 증가할 수도, 2가 증가할 수도 있는데요. 이를 해결하기 위해서는 상호 배제(Mutual Exclusion), 즉 한 번에 하나의 스레드만 자원에 접근하는 것을 허용해야 합니다.

 

 

pthread_mutex, 락(Lock)으로 안전하게 보호하기

pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;

pthread_mutex_lock(&lock);
// 공유 자원 접근 (임계 구역)
pthread_mutex_unlock(&lock);
  • mutex_lock: 잠금 획득 (다른 스레드는 대기)
  • mutex_unlock: 잠금 해제 (다음 대기 스레드가 진입)

주의할 점으로, 락을 걸었으면 반드시 풀어야 하는데요. 그렇지 않으면 여러 스레드가 서로의 자원을 요구하며 무한정 대기하는 현상인 데드락(deadlock)이 발생할 수 있습니다.

 

 

멀티스레딩에서의 흔한 함정들

  • 비결정성: 실행 순서에 따라 결과가 매번 달라지는 현상으로, 디버깅을 어렵게 한다.
  • 데드락: A는 B의 락, B는 A의 락을 기다리면서 무한정 대기하는 현상으로, 프로그램이 멈추게 된다.

예방 전략

  • 락을 거는 순서를 일관되게 유지
  • 타임아웃 등으로 잠금 시간 제한 걸기
  • 락 범위를 최소화 (필요한 부분만)

 

Tiny 서버를 멀티스레드로 확장하기

기존 Tiny 서버는 순차적으로 클라이언트 요청을 처리하는 구조였습니다. 다만 이런 구조는 하나의 요청을 처리 중일 경우 다른 요청은 기다려야 하는 문제가 있었는데요. 이를 스레드 기반 동시성 서버로 바꿈으로써 이러한 문제를 해결할 수 있습니다.

while (1) {
    int connfd = accept(...);
    int *pconnfd = malloc(sizeof(int));
    *pconnfd = connfd;
    pthread_create(&tid, NULL, thread_func, pconnfd);
}
  • pthread_create()로 클라이언트 연결마다 새 스레드를 생성한다
  • 소켓 파일 디스크립터(connfd)는 malloc으로 복사본을 만든 뒤 전달해야 안정적이다
  • thread_func() 안에서 요청 처리 후 free() 를 호출해줘야 메모리 누수가 생기지 않는다

 

마무리 요약

  • 스레드는 프로세스보다 가볍고 빠르다
  • 공유 메모리는 편하지만, race condition을 일으킬 수 있다
  • pthread_mutex로 락을 걸어 안정성을 확보한다
  • 스레드 기반 서버는 요청 처리량 향상, 응답 시간 단축에 큰 도움이 된다
저작자표시 비영리 변경금지 (새창열림)

'크래프톤 정글 > 컴퓨터구조(CSAPP)' 카테고리의 다른 글

[CSAPP 10장 골라읽기] 10.5 안정적인 읽기와 쓰기를 위한 RIO 패키지 완전정복  (0) 2025.05.05
[CSAPP 11장 완전 정복] 11.5~11.6(Part3) Tiny 웹 서버 확장성과 실전 응용  (1) 2025.05.03
[CSAPP 11장 완전 정복] 11.5~11.6(Part 2) Tiny 웹 서버 구조 뜯어보기  (1) 2025.05.03
[CSAPP 11장 완전 정복] 11.5~11.6(Part 1) 웹 서버의 세계로 한 걸음, Tiny는 왜 필요한가?  (0) 2025.05.03
CSAPP 11.5~11.6 rawdata 공유 (전체 학습 목표, 학습 정리 자료)  (0) 2025.05.03
'크래프톤 정글/컴퓨터구조(CSAPP)' 카테고리의 다른 글
  • [CSAPP 10장 골라읽기] 10.5 안정적인 읽기와 쓰기를 위한 RIO 패키지 완전정복
  • [CSAPP 11장 완전 정복] 11.5~11.6(Part3) Tiny 웹 서버 확장성과 실전 응용
  • [CSAPP 11장 완전 정복] 11.5~11.6(Part 2) Tiny 웹 서버 구조 뜯어보기
  • [CSAPP 11장 완전 정복] 11.5~11.6(Part 1) 웹 서버의 세계로 한 걸음, Tiny는 왜 필요한가?
그냥사람_
그냥사람_
IT 관련 포스팅을 합니다. 크래프톤 정글 8기 정경호
  • 그냥사람_
    그냥코딩
    그냥사람_
  • 전체
    오늘
    어제
    • 글 전체보기 N
      • 크래프톤 정글
        • 로드 투 정글(입학시험)
        • CS기초(키워드, 개념정리)
        • 컴퓨터구조(CSAPP)
        • Code 정글(C언어)
        • Equipped in 정글(나만무)
        • 마이 정글(WIL, 에세이)
      • 자료구조&알고리즘
        • 자료구조
        • 알고리즘
      • Flutter N
      • 일상
  • 블로그 메뉴

    • 홈
  • 링크

    • Github
  • hELLO· Designed By정상우.v4.10.3
그냥사람_
[CSAPP 12장 골라읽기] 12.3 스레드를 이용한 동시성 프로그래밍 빠삭하게 이해하기
상단으로

티스토리툴바