C++/STL

[C++] std::async, std::thread (1)

sseram 2023. 4. 9. 18:24
반응형

둘 다 비동기 작업을 수행하기 위해 만드는 것은 동일.

다만 몇 가지의 차이는 있다.

 

쓰면서 가장 와닿았던 두 가지의 특성이 있는데,

 

 

 

 

1. std::thread는 그저 thread를 하나 만들 뿐이다. 그에 관한 관리는 직접 해야한다.

 반면에 std::async는 자체 thread pool을 가지고 있어 관리에 대해서는 좀 놓아도 상관없다.

 

 

2. std::thread는 해당 함수를 통해 값을 가져오는 건 좀 귀찮아서, 주로 watchdog 같은 곳에 사용하게 되더라.

반면 std::async는 만드는 순간 future object를 되돌려주기 때문에, 해당 함수에서 값을 얻어오는 대에 특화되어있다.

 

 

 

 

여기에선 첫 번째에 관해서만 확인해보자.

 

#include <future>
#include <iostream>

void func() {
	std::cout << "func start" << std::endl;
	std::this_thread::sleep_for(std::chrono::seconds(2));
	std::cout << "func end" << std::endl;
}

int main() {
	std::cout << "main start" << std::endl;

	auto t1 = std::thread(func);

	std::cout << "main end" << std::endl;

	return 0;
}

 

func라는 함수를 만들고, 해당 함수를 thread를 통하여 실행시켰다.

이 부분을 빌드하여 돌리면?

 

 

빠르게 에러가 뜬다.

 

이유는 thread로 만든 t1 때문.

 

main에서 자식 쓰레드를 만들었는데, 자식 쓰레드가 끝나기 전에 부모가 먼저 죽어버렸기 때문에 저래 뜬다.

정확히 말하면... func 에서 수행해야 할 건들은 전부 끝났다. 하지만 끝나기만 했고, 내가 만든 thread를 회수하지 않았다. 이전에 smart pointer 없었을 때의 new와 delete 같은느낌.

 

위 부분을 해결하려면

 

 

#include <future>
#include <iostream>

void func() {
	std::cout << "func start" << std::endl;
	std::this_thread::sleep_for(std::chrono::seconds(2));
	std::cout << "func end" << std::endl;
}

int main() {
	std::cout << "main start" << std::endl;

	auto t1 = std::thread(func);

	std::cout << "main end" << std::endl;

	if (t1.joinable())
		t1.join();

	return 0;
}

이런 식으로 만든 thread를 직접 join 시켜 주거나,

 

 

 

#include <future>
#include <iostream>

void func() {
	std::cout << "func start" << std::endl;
	std::this_thread::sleep_for(std::chrono::seconds(2));
	std::cout << "func end" << std::endl;
}

int main() {
	std::cout << "main start" << std::endl;

	std::thread(func).detach();

	std::cout << "main end" << std::endl;

	return 0;
}

이런 식으로 detach 해 버려서 본인의 일이 끝나면 알아서 죽게끔 해 주면 된다.

 

위 상황에서는, 자식보다 부모가 먼저 죽어버려서 자식 thread가 미처 다 죽지 못하고 끝나버렸다.

 

 

 

 

 

 

그러면 std::async 는?

 

 

#include <future>
#include <iostream>

void func() {
	std::cout << "func start" << std::endl;
	std::this_thread::sleep_for(std::chrono::seconds(2));
	std::cout << "func end" << std::endl;
}

int main() {
	std::cout << "main start" << std::endl;

	auto t1 = std::async(func);

	std::cout << "main end" << std::endl;

	return 0;
}

 

 

깔끔 그자체.

 

 

 

 

 

2번째 ->

 

https://donot-simsim.tistory.com/37

 

 

 

 

 

* 잘못된 정보는 알려주시면 너무너무 감사합니다.

반응형