IMCAT.DEV
로그인 가입
C++ 고급 비동기

C++ C++의 동시성 (Concurrency)

C++ C++의 동시성 (Concurrency) — 고급

C++의 동시성 (Concurrency)

1. 도입 (왜 배워야 하는가)

C++의 동시성은 멀티스레딩과 병렬 프로그래밍을 통해 프로그램의 성능을 극대화할 수 있는 강력한 기법입니다. 현대의 컴퓨터는 다수의 코어를 가진 경우가 많아, 이를 활용하여 작업을 동시에 수행하면 실행 시간을 획기적으로 줄일 수 있습니다. 예를 들어, 대규모 데이터 처리, 게임 개발, 웹 서버의 요청 처리 등 여러 분야에서 동시성을 활용하여 성능을 향상시킵니다.

반면, 동시성을 제대로 이해하지 못하면 데드락, 레이스 컨디션과 같은 문제가 발생할 수 있습니다. 이러한 문제는 프로그램의 비정상 종료나 버그를 발생시키며, 결국 사용자 경험을 저하시킬 수 있습니다.

2. 핵심 개념 설명

스레드 (Thread)

  • 스레드는 프로세스 내에서 실행되는 경량의 실행 단위입니다. 하나의 프로세스는 여러 개의 스레드를 가질 수 있습니다.
  • 비유: 스레드는 회사의 직원과 같고, 프로세스는 그 회사입니다. 회사가 여러 일을 동시에 처리하기 위해 여러 직원이 필요합니다.
  • 동기화 (Synchronization)

  • 여러 스레드가 공유 자원에 접근할 때 충돌을 방지하기 위해 동기화가 필요합니다.
  • 비유: 여러 사람이 동시에 한 개의 펜을 사용하고자 할 때, 펜을 사용하는 순서를 정하는 것과 같습니다.
  • 레이스 컨디션 (Race Condition)

  • 두 개 이상의 스레드가 공유 자원에 동시에 접근하여 결과가 예상과 다르게 되는 상황입니다.
  • 비유: 두 사람이 동시에 문을 열려고 할 때, 누가 먼저 열지에 따라 결과가 달라지는 상황입니다.
  • 용어정의
    스레드프로세스 내에서 실행되는 독립적인 실행 단위
    동기화여러 스레드가 공유 자원에 접근할 때 충돌 방지
    레이스 컨디션여러 스레드가 동시에 자원을 접근하여 발생하는 오류

    3. 기본 코드 예제

    아래는 C++의 스레드를 사용하는 기본 예제입니다.

    #include <iostream>
    #include <thread>
    
    void hello() {
        std::cout << "Hello from thread!" << std::endl;
    }
    
    int main() {
        std::thread t(hello); // hello 함수로 새로운 스레드 생성
        t.join(); // 메인 스레드가 t가 끝날 때까지 기다림
        return 0;
    }

    실행 결과

    Hello from thread!

    코드 한 줄씩 동작 설명

    1. #include <iostream>: 입출력을 위한 헤더 파일 포함.
    2. #include <thread>: 스레드를 사용하기 위한 헤더 파일 포함.
    3. void hello(): 스레드가 실행할 함수 정의.
    4. std::cout << "Hello from thread!" << std::endl;: 스레드가 실행될 때 메시지를 출력.
    5. int main(): 프로그램의 시작점.
    6. std::thread t(hello);: hello 함수를 실행하는 새로운 스레드 t 생성.
    7. t.join();: 메인 스레드가 t 스레드의 종료를 기다림.
    8. return 0;: 프로그램 종료.
    9. 4. 실전 활용 예제

      예제 1: 쇼핑몰에서 장바구니 업데이트

      쇼핑몰에서 사용자가 장바구니에 물건을 추가할 때, 각 사용자의 요청을 동시에 처리해야 합니다.

      #include <iostream>
      #include <thread>
      #include <vector>
      #include <mutex>
      
      std::mutex mtx; // 동기화를 위한 뮤텍스
      std::vector<int> cart; // 장바구니
      
      void add_to_cart(int item) {
          mtx.lock(); // 뮤텍스 잠금
          cart.push_back(item); // 장바구니에 아이템 추가
          mtx.unlock(); // 뮤텍스 잠금 해제
          std::cout << "Added item " << item << " to cart." << std::endl;
      }
      
      int main() {
          std::thread t1(add_to_cart, 1);
          std::thread t2(add_to_cart, 2);
          
          t1.join();
          t2.join();
      
          std::cout << "Items in cart: ";
          for (int item : cart) {
              std::cout << item << " ";
          }
          return 0;
      }

      예제 2: 데이터 분석

      대량의 데이터를 처리하는 경우, 여러 스레드를 활용하여 데이터를 병렬로 분석할 수 있습니다.

      #include <iostream>
      #include <thread>
      #include <vector>
      
      void process_data(int start, int end) {
          for (int i = start; i < end; ++i) {
              // 데이터 처리 로직 (여기서는 단순 출력)
              std::cout << "Processing data " << i << std::endl;
          }
      }
      
      int main() {
          const int dataSize = 100;
          std::thread t1(process_data, 0, dataSize/2);
          std::thread t2(process_data, dataSize/2, dataSize);
          
          t1.join();
          t2.join();
          
          return 0;
      }

      5. 흔한 실수와 주의사항

      실수 1: 뮤텍스 잠금을 잊는 것

      // 잘못된 코드
      void add_to_cart(int item) {
          // mtx.lock(); // 잠금 누락
          cart.push_back(item);
          // mtx.unlock(); // 잠금 해제 누락
      }
      
      // 올바른 코드
      void add_to_cart(int item) {
          mtx.lock();
          cart.push_back(item);
          mtx.unlock();
      }
    10. 뮤텍스를 잠그지 않으면 레이스 컨디션이 발생할 수 있습니다.
    11. 실수 2: join() 호출 누락

      // 잘못된 코드
      std::thread t1(add_to_cart, 1);
      // t1.join(); // join 호출 누락
      
      // 올바른 코드
      std::thread t1(add_to_cart, 1);
      t1.join();
    12. join()을 호출하지 않으면 메인 스레드가 종료되기 전에 t1 스레드가 종료되지 않을 수 있습니다.
    13. 6. 정리

    14. C++의 동시성은 멀티스레딩을 통해 프로그램의 성능을 향상시킬 수 있습니다.
    15. 스레드, 동기화, 레이스 컨디션 등의 개념을 이해하는 것이 중요합니다.
    16. 뮤텍스 등을 활용해 공유 자원에 대한 접근을 안전하게 처리하는 방법을 익혀야 합니다.
    17. 다음에 학습하면 좋은 주제로는 "C++의 비동기 프로그래밍"이나 "병렬 알고리즘"을 추천합니다.