728x90
멀티 스레드를 관리하기 위해 vector를 이용하려고 해도 스레드는 복사생성자를 지원하지 않아 일반 데이터와 동일하게 처리를 할 수 없다.
vector를 이용해 멀티스레드를 보관하려는 아래 예제를 보자.
#include <vector>
#include <thread>
#include <algorithm>
#include <functional>
void do_work(unsigned id)
{}
int main()
{
// 참고..
std::thread t1(&do_work, 1);
v1.push_back(t1); // error. 복사 생성자가 필요한데..
// std::thread 는 복사 될수 없는타입
// create.. 10 thread
std::vector<std::thread> v1; // 초기 크기 0
for (int i = 0; i < 10; i++)
{
// 참고..
std::thread t1(&do_work, 1);
v1.push_back(t1); // error. 복사 생성자가 필요한데..
// std::thread 는 복사 될수 없는타입
}
}
vector에 스레드를 보관하려고 하면 push_back 하는 시점에 복사 생성자가 필요한데 thread가 지원하지 않기에 vector를 사용할 수가 없다.
임시객체를 이용하기
push_back에 넣을 때 임시객체로 생성하면 vector에 넣는 게 가능하다.
#include <vector>
#include <thread>
#include <algorithm>
#include <functional>
void do_work(unsigned id)
{}
int main()
{
// 2. create.. 10 thread
std::vector<std::thread> v1; // 초기 크기 0
for (int i = 0; i < 10; i++)
{
// 임시객체 형태로 넣기
v1.push_back( std::thread(&do_work, 1) );
}
// 모두 join
for (auto& t : v1)
t.join();
}
std::thread(&do_work, 1) 이 코드는 임시 객체로 생성(rvalue)된 것이기에 복사가 아니라 move로 대입된 것이기에 넣는 게 가능하다.
emplace_back 이용하기
emplace_back 함수 원형을 먼저 확인해 보자.
template< class... Args >
void emplace_back( Args&&... args ); |
(since C++11) (until C++17) |
emplace_back는 push_back과 달리 삽입 객체를 받는 게 아니고 삽입할 객체의 생성자를 위한 인자를 받는다. 그리고 std:vector 내에서 직접 객체를 생성하여 삽입한다.
#include <vector>
#include <thread>
#include <algorithm>
#include <functional>
void do_work(unsigned id)
{}
int main()
{
// 2. create.. 10 thread
std::vector<std::thread> v1;
for (int i = 0; i < 10; i++)
{
//std::thread t1(&do_work, 1);
//v1.push_back(t1);
// push_back 대신에 emplace_back 으로 넣기
// => push_back : 대상타입의 객체를 만들어서 전달
// => emplace_back : 대상타입을 만들기 위한 생성자 인자전달
v1.emplace_back(&do_work, 1);
}
// 모두 join
for (auto& t : v1)
t.join();
}
v1.emplace_back(&do_work, 1) 를 보면
v1는 std::thread 타입의 vector 이기에 thread의 인자만 전달하면, vector 내에서 thread 객체를 생성하여 삽입된다.
참고
for문 대신에 for_each를 쓸 수도 있다.
#include <vector>
#include <thread>
#include <algorithm>
#include <functional>
void do_work(unsigned id)
{}
int main()
{
// 2. create.. 10 thread
std::vector<std::thread> v1;
for (int i = 0; i < 10; i++)
{
v1.push_back( std::thread(&do_work, 1) );
}
// 모두 join
// for (auto& t : v1)
// t.join();
std::for_each(v1.begin(), v1.end(),
[](auto& t) { t.join(); } );
}
참고
* 본 글에 예제 코드는 코드누리 교육을 받으면서 제공된 샘플코드를 활용하였습니다.
728x90
728x90
'L C++ > Concurrency' 카테고리의 다른 글
race condition : 스레드를 병렬로 그냥 동작 시키면 안 되는 이유 (0) | 2023.09.19 |
---|---|
[Concurrency] Function Templates(함수 템플릿)을 스레드로 실행하기 (0) | 2023.09.05 |
[Concurrency] 주요 기능 member type / class / functions 정리 (0) | 2023.08.01 |
[Concurrency] 인자와 callable object (0) | 2023.07.24 |
[Concurrency] 좀비 스레드 생성될 수 있는가? (0) | 2023.07.18 |