728x90

자주 사용되진 않지만 매우 오래걸리는 함수가 있을 때 유용한 기능.

#include <iostream>
using namespace std;

#include <future>

int VeryLongtimeJob()
{
	// 뭔가 되게 오래걸리는 작업
}

int main()
{
	future<int> future = async(launch::async, VeryLongtimeJob);

	// Other Job

	int result = future.get();
}
 

사용 방법은 간단하다.

future에 함수로 받아줄 인자를 지정하고 launch::async, launch::deffered 둘 중 하나를 선택해주면된다.

async의 경우 단어 그대로 비동기 적으로 동작하게 하며 새로운 스레드를 하나 생성하여 해당 함수를 실행한다. 결과를 가져올 때는 get함수를 사용해서 가져오며, 만약 get을 호출하는 시점에도 끝나지 않았었다고 하면 다 끝날 때 까지 기다렸다가 결과를 반환하게 된다.

deffered의 경우도 단어 그대로 지연 실행한다는 의미이다. 새로운 스레드를 만드는 것이 아니라 나중에 실행하라고 알려주는 느낌이며, get을 사용해서 가져오려고 할 때 실행된다.

클래스의 내부 함수를 호출하는 것도 가능하다. 이 경우 객체가 생성되어 있어야 한다.

#include <iostream>
using namespace std;

#include <future>

class Job
{
public:
	int VeryLongtimeJob()
	{
		// 뭔가 되게 오래걸리는 작업
	}
};

int main()
{
	Job job;
	future<int> future = async(launch::async, &Job::VeryLongtimeJob, job);

	// Other Job

	int result = future.get();
}
 

 

promise

future와 비슷하게 당장은 아닌데 후에라도 필요할 때 사용할 수 있는 방법이다.

#include <iostream>
using namespace std;

#include <future>

void PromiseFunc(promise<int>&& promise)
{
	promise.set_value(1);
}

int main()
{
	promise<int> promise;
	future<int> future = promise.get_future();

	thread t(PromiseFunc, std::move(promise));

	int result = future.get();
	cout << result << endl;

	t.join();
}
 

스레드를 하나 생성하여 해당 스레드에게 std::move로 소유권을 넘겨주고 promise객체에서 얻을 수 있는 future객체만 메인스레드에서 보유하고 있으면 후에 get함수를 통해 promise에 저장된 값을 가져올 수 있다. return값이 아니어도 가능하기 때문에 함수 중간에 값을 가져올 때 용이할 것 같다.

 

packaged_task

앞의 두개보다 task단위로써 더 많은 일을 해야할 때 유용할 것 같은 기능이다.

#include <iostream>
using namespace std;

#include <future>

void PackagedTaskThreadFunc(packaged_task<int(void)>&& task)
{
	task();
}

int PackagedTaskFunc()
{
	return 1;
}

int main()
{
	packaged_task<int(void)> pt(PackagedTaskFunc);
	future<int> future = pt.get_future();

	thread t(PackagedTaskThreadFunc, move(pt));

	int result = future.get();
	cout << result;

	t.join();
}
 

앞의 두 가지 보다 사용방법은 좀 더 복잡한데 packaged_task라는 task단위로 실행해야할 일을 스레드에게 전달해주는 것인데 만약 PackagedTaskThreadFunc의 인자가 하나가 아니라면 여러개의 task를 전달하여 일을 하도록 할 수 있을 것이다.

 

728x90

'C++ > 멀티스레드' 카테고리의 다른 글

Lock Free Stack  (0) 2023.05.14
Condition Variable  (1) 2023.05.14
Event  (0) 2023.05.14
SpinLock  (0) 2023.05.14
DeadLock  (0) 2023.05.14

+ Recent posts