2026년 상식닷컴 선정 식당 & 카페 리스트
최근에 오픈한 호텔을 찾는다면 살펴보세요

C++에서 std::thread의 기본 사용법은?

Q1: std::thread란 무엇인가요?
A1: std::thread는 C++11부터 표준 라이브러리에 추가된 스레딩 라이브러리로, 멀티스레딩 프로그래밍을 쉽게 구현할 수 있도록 도와줍니다. 스레드는 병렬로 실행 가능한 작업 단위입니다.

---

Q2: std::thread를 사용하려면 어떤 헤더를 포함해야 하나요?
A2: ` include ` 헤더를 포함해야 하며, 스레드 클래스와 관련 기능들이 제공됩니다.

---

Q3: std::thread 객체는 어떻게 생성하나요?
A3: std::thread 객체는 실행할 함수 또는 함수 객체와 그 함수에 전달할 인자를 생성자에 넘겨서 생성합니다.

```cpp
include

void foo(int x) {
// 작업 내용
}

int main() {
std::thread t(foo, 10); // foo(10)을 새 스레드에서 실행
t.join(); // 메인 스레드에서 t 스레드가 종료될 때까지 대기
return 0;
}
```

---

Q4: 스레드를 생성할 때 전달할 수 있는 함수 종류는 무엇인가요?
A4:
- 자유 함수 (free function)
- 람다 함수
- 멤버 함수 (객체와 함께 호출 필요)
- 함수 객체 (functor)

예:

```cpp
include
include

struct Functor {
void operator()(int x) {
std::cout << "Functor: " << x << std::endl;
}
};

class Foo {
public:
void memberFunc(int x) {
std::cout << "Member Func: " << x << std::endl;
}
};

int main() {
std::thread t1([](int x){ std::cout << "Lambda: " << x << std::endl; }, 5);

Functor f;
std::thread t2(f, 10);

Foo foo;
std::thread t3(&Foo::memberFunc, &foo, 15);

t1.join();
t2.join();
t3.join();
}
```

---

Q5: std::thread 객체를 실행한 후 반드시 해야 할 작업은 무엇인가요?
A5:
- 스레드를 종료시켜야 하며, `join()` 혹은 `detach()`를 호출해야 합니다.
- `join()`은 메인 스레드가 해당 스레드가 끝날 때까지 기다리는 것이고,
- `detach()`는 스레드를 분리하여 백그라운드에서 실행하게 합니다.

만약 어떤 것도 호출하지 않고 std::thread 객체가 소멸되면 프로그램이 `std::terminate()`를 호출해 종료됩니다.

---

Q6: std::thread의 기본적인 사용 예시는 어떻게 되나요?
A6:

```cpp
include
include

void say_hello() {
std::cout << "Hello from thread!" << std::endl;
}

int main() {
std::thread t(say_hello); // say_hello를 별도 스레드에서 실행
t.join(); // 스레드 종료를 기다림
std::cout << "Hello from main!" << std::endl;
return 0;
}
```

---

Q7: 스레드 생성 시 인자 전달은 어떻게 하나요?
A7: 함수 인자를 std::thread 생성자에 추가로 넘기면, 스레드 함수에서 해당 인자를 받습니다. 인자는 복사되거나 이동됩니다.

```cpp
void print_num(int n) {
std::cout << n << std::endl;
}

std::thread t(print_num, 42);
```

참고로 참조 인자를 넘기려면 `std::ref`를 사용해야 합니다. 스레드 내부에서 인자를 복사하지 않고 참조로 받게 됩니다.

```cpp
include // std::ref

void print_num_ref(int& n) {
std::cout << n << std::endl;
}

int main() {
int x = 100;
std::thread t(print_num_ref, std::ref(x));
t.join();
}
```

---

Q8: std::thread 객체를 복사할 수 있나요?
A8: 아니요. std::thread는 복사 생성자가 삭제되어 복사할 수 없습니다. 다만, 이동 생성자와 이동 대입 연산자는 제공하므로 이동만 가능합니다.

---

Q9: 여러 개의 std::thread를 관리하는 방법은?
A9: std::vector 같은 컨테이너에 저장하여 관리할 수 있습니다. 종료 전에 모든 스레드에 대해 `join()` 혹은 `detach()`를 호출해야 합니다.

```cpp
include
include
include

void worker(int id) {
std::cout << "Worker " << id << " start\n";
// 작업 ...
std::cout << "Worker " << id << " end\n";
}

int main() {
std::vector threads;
for (int i = 0; i < 5; ++i) {
threads.emplace_back(worker, i);
}

for (auto& t : threads) {
t.join();
}
}
```

---

Q10: std::thread 사용 시 주의할 점은 무엇인가요?
A10:
- 스레드가 예외를 던질 경우 해당 예외는 별도 스레드 영역에서 발생하므로 주 스레드와 별개로 처리해야 합니다.
- 공유 자원 접근 시 동기화 (mutex 등)를 사용해야 데이터 경합을 방지합니다.
- `join()` 혹은 `detach()`를 반드시 호출해 스레드 객체가 소멸될 때 종료 상태가 아니면 안 됩니다.
- 참조 전달 시 `std::ref`를 사용해야 합니다.

---

요약하면, std::thread는 함수나 함수 객체, 람다 등을 별도의 스레드로 실행시킬 수 있으며, 생성 시 인자를 넘기고, 실행 후 반드시 join() 또는 detach()를 호출하여 스레드 종료 처리를 해주어야 하는 C++ 표준 라이브러리 클래스입니다.
C++에서 `std::thread`는 C++11부터 도입된 멀티스레딩을 위한 클래스입니다. 이를 통해 여러 스레드를 생성하고 관리할 수 있으며, 병렬 처리를 통해 프로그램의 성능을 향상시킬 수 있습니다. `std::thread`의 기본 사용법에 대해 자세히 알아보겠습니다. 1. 기본 개념 `std::thread`는 C++ 표준 라이브러리의 `` 헤더에 정의되어 있습니다. 스레드는 독립적으로 실행되는 코드의 흐름을 의미하며, 여러 스레드를 사용하면 CPU의 여러 코어를 활용하여 작업을 병렬로 수행할 수 있습니다. 2. 스레드 생성 스레드를 생성하려면 `std::thread` 객체를 생성할 때 실행할 함수나 함수 객체를 인자로 전달합니다. 다음은 기본적인 스레드 생성 예제입니다. ```cpp include include void hello() { std::cout << "Hello from thread!" << std::endl; } int main() { std::thread t(hello); // hello 함수를 실행하는 스레드 생성 t.join(); // 메인 스레드가 t 스레드가 종료될 때까지 대기 return 0; } ``` 위의 코드에서 `hello` 함수는 새로운 스레드에서 실행됩니다. `t.join()`은 메인 스레드가 `t` 스레드가 종료될 때까지 기다리도록 합니다. 만약 `join()`을 호출하지 않으면 프로그램이 종료될 때 `t` 스레드가 아직 실행 중일 수 있으며, 이는 정의되지 않은 동작을 초래할 수 있습니다. 3. 스레드에 인자 전달 스레드에 인자를 전달하려면, `std::thread` 생성자에 인자를 추가로 전달하면 됩니다. 예를 들어: ```cpp include include void printNumbers(int n) { for (int i = 0; i < n; ++i) { std::cout << i << " "; } std::cout << std::endl; } int main() { std::thread t(printNumbers, 10); // printNumbers 함수에 10을 인자로 전달 t.join(); return 0; } ``` 위의 예제에서 `printNumbers` 함수는 0부터 n-1까지의 숫자를 출력합니다. `std::thread` 생성자에 `printNumbers`와 함께 인자 `10`을 전달하여 스레드를 생성합니다. 4. 스레드의 복사 및 이동 `std::thread` 객체는 복사할 수 없지만 이동할 수 있습니다. 스레드를 다른 스레드로 이동하려면 `std::move`를 사용합니다. ```cpp include include include void task() { std::cout << "Task is running!" << std::endl; } int main() { std::thread t1(task); std::thread t2 = std::move(t1); // t1을 t2로 이동 if (t1.joinable()) { std::cout << "t1 is joinable" << std::endl; // t1은 더 이상 joinable하지 않음 } t2.join(); // t2 스레드가 종료될 때까지 대기 return 0; } ``` 5. 스레드의 종료 스레드는 `join()` 또는 `detach()`를 호출하여 종료할 수 있습니다. `join()`은 스레드가 종료될 때까지 기다리지만, `detach()`는 스레드를 분리하여 독립적으로 실행되도록 합니다. 분리된 스레드는 더 이상 메인 스레드와 연결되지 않으며, 메인 스레드가 종료되더라도 계속 실행됩니다. ```cpp include include include void detachedTask() { std::this_thread::sleep_for(std::chrono::seconds(1)); std::cout << "Detached task finished!" << std::endl; } int main() { std::thread t(detachedTask); t.detach(); // 스레드를 분리 std::cout << "Main thread is doing something else..." << std::endl; std::this_thread::sleep_for(std::chrono::seconds(2)); // 메인 스레드가 잠시 대기 return 0; // 메인 스레드가 종료되더라도 detachedTask는 계속 실행됨 } ``` 6. 스레드 안전성 스레드를 사용할 때는 데이터 경쟁(data race)과 같은 문제를 피하기 위해 스레드 안전성을 고려해야 합니다. 이를 위해 `std::mutex`, `std::lock_guard`, `std::unique_lock` 등을 사용하여 공유 자원에 대한 접근을 제어할 수 있습니다. ```cpp include include include std::mutex mtx; // 뮤텍스 객체 int sharedCounter = 0; void increment() { for (int i = 0; i < 1000; ++i) { std::lock_guard lock(mtx); // 뮤텍스 잠금 ++sharedCounter; } } int main() { std::thread t1(increment); std::thread t2(increment); t1.join(); t2.join(); std::cout << "Final counter value: " << sharedCounter << std::endl; return 0; } ``` 위의 예제에서 `std::lock_guard`를 사용하여 `sharedCounter`에 대한 접근을 안전하게 보호합니다. 두 개의 스레드가 동시에 `increment` 함수를 호출하더라도 데이터 경쟁이 발생하지 않습니다. 결론 `std::thread`는 C++에서 멀티스레딩을 구현하는 강력한 도구입니다. 스레드를 생성하고 관리하는 기본적인 방법을 이해하고, 스레드 안전성을 확보하기 위해 적절한 동기화 기법을 사용하는 것이 중요합니다. 이를 통해 C++ 프로그램의 성능을 향상시키고, 복잡한 작업을 효율적으로 처리할 수 있습니다.
작성자: 김서하 [비회원] | 작성일자: 1년 전 2024-09-20 17:11:34
조회수: 147 | 댓글: 0 | 좋아요: 0 | 싫어요: 0
내용이 부정확하다면 싫어요를 클릭해주세요.