멀티스레딩의 중요성
멀티스레딩은 여러 스레드를 사용하여 동시에 작업을 수행함으로써 프로그램의 성능을 향상시키는 기법입니다. 이를 통해 CPU 자원을 효율적으로 사용하고, 응답성을 높일 수 있습니다.
기본 용어
- 스레드(Thread): 프로세스 내에서 독립적으로 실행되는 코드의 흐름입니다.
- 멀티스레딩(Multithreading): 여러 스레드를 사용하여 동시에 여러 작업을 수행하는 기법입니다.
- 병렬 처리(Parallel Processing): 여러 프로세서나 코어에서 동시에 작업을 수행하는 기법입니다.
- 경합(Concurrency): 여러 작업이 동시에 실행되는 것처럼 보이는 상태입니다.
C++에서의 멀티스레딩
C++11부터 표준 라이브러리에서 멀티스레딩을 지원하는 기능이 도입되었습니다. std::thread
클래스를 사용하여 스레드를 생성하고 관리할 수 있습니다.
기본 예제
1. 스레드 생성
스레드를 생성하고 실행하는 기본 예제입니다.
#include <iostream>
#include <thread>
void threadFunction() {
std::cout << "Hello from thread!" << std::endl;
}
int main() {
std::thread t(threadFunction); // 스레드 생성
t.join(); // 메인 스레드가 생성된 스레드가 종료될 때까지 대기
return 0;
}
2. 인자 전달
스레드에 인자를 전달하는 예제입니다.
#include <iostream>
#include <thread>
void threadFunction(int x) {
std::cout << "Thread function with argument: " << x << std::endl;
}
int main() {
int value = 42;
std::thread t(threadFunction, value); // 스레드 생성 시 인자 전달
t.join(); // 메인 스레드가 생성된 스레드가 종료될 때까지 대기
return 0;
}
3. 람다 함수 사용
람다 함수를 사용하여 스레드를 생성하는 예제입니다.
#include <iostream>
#include <thread>
int main() {
std::thread t([]{
std::cout << "Hello from lambda function thread!" << std::endl;
});
t.join(); // 메인 스레드가 생성된 스레드가 종료될 때까지 대기
return 0;
}
스레드 동기화
멀티스레딩에서 여러 스레드가 공유 자원에 접근할 때 동기화가 필요합니다. 동기화 문제를 해결하지 않으면 경합 조건(race condition)이나 데드락(deadlock) 같은 문제가 발생할 수 있습니다.
뮤텍스(Mutex)
뮤텍스는 상호 배제를 구현하는 동기화 기법입니다. std::mutex
클래스를 사용하여 뮤텍스를 생성하고, lock
과 unlock
함수를 사용하여 뮤텍스를 잠그고 해제할 수 있습니다.
예제 코드
#include <iostream>
#include <thread>
#include <mutex>
std::mutex mtx;
void printMessage(const std::string& msg) {
std::lock_guard<std::mutex> lock(mtx);
std::cout << msg << std::endl;
}
int main() {
std::thread t1(printMessage, "Hello from thread 1");
std::thread t2(printMessage, "Hello from thread 2");
t1.join();
t2.join();
return 0;
}
위 예제에서는 std::lock_guard
를 사용하여 자동으로 뮤텍스를 잠그고 해제합니다.
실습 문제
문제 1: 멀티스레딩과 동기화 구현하기
다음 코드에서 멀티스레딩을 사용하여 두 개의 스레드가 동시에 카운트를 증가시키도록 구현하세요. 동시에 뮤텍스를 사용하여 경합 조건을 방지하세요.
main.cpp
#include <iostream>
#include <thread>
#include <mutex>
int counter = 0;
std::mutex mtx;
void incrementCounter() {
for (int i = 0; i < 100000; ++i) {
counter++;
}
}
int main() {
std::thread t1(incrementCounter);
std::thread t2(incrementCounter);
t1.join();
t2.join();
std::cout << "Final counter value: " << counter << std::endl;
return 0;
}
해답:
main.cpp (동기화 추가)
#include <iostream>
#include <thread>
#include <mutex>
int counter = 0;
std::mutex mtx;
void incrementCounter() {
for (int i = 0; i < 100000; ++i) {
std::lock_guard<std::mutex> lock(mtx);
counter++;
}
}
int main() {
std::thread t1(incrementCounter);
std::thread t2(incrementCounter);
t1.join();
t2.join();
std::cout << "Final counter value: " << counter << std::endl;
return 0;
}
이제 열다섯 번째 날의 학습을 마쳤습니다. 멀티스레딩의 기본 개념과 스레드 동기화 기법을 이해하고, 실습 문제를 통해 이를 구현하는 방법을 학습했습니다.
질문이나 피드백이 있으면 언제든지 댓글로 남겨 주세요. 내일은 "std::thread와 동기화 기법"에 대해 학습하겠습니다.
'-----ETC----- > C++ 성능 최적화 및 고급 테크닉 시리즈' 카테고리의 다른 글
[C++ 성능 최적화 및 고급 테크닉] Day 17: 병렬 알고리즘과 std::async (0) | 2024.08.01 |
---|---|
[C++ 성능 최적화 및 고급 테크닉] Day 14: CRTP (Curiously Recurring Template Pattern) 사용법 (0) | 2024.08.01 |
[C++ 성능 최적화 및 고급 테크닉] Day 12: C++11/14/17/20의 새로운 기능 활용 (0) | 2024.08.01 |
[C++ 성능 최적화 및 고급 테크닉] Day 13: 고급 상속 및 다형성 기법 (0) | 2024.08.01 |
[C++ 성능 최적화 및 고급 테크닉] Day 11: 표현식 템플릿 (Expression Templates) (0) | 2024.08.01 |