프로그래밍/Parallel Programming

병렬 프로그래밍 Parallel Programming - cancellation_token 특성

nanze 2022. 1. 5. 13:51
반응형

이전 정리글

2022.01.03 - [프로그래밍/Parallel Programming] - 병렬 프로그래밍 Parallel Programming - cancellation_token

 

병렬 프로그래밍 Parallel Programming - cancellation_token

이전 정리글은 2022.01.03 - [프로그래밍/Parallel Programming] - 병렬 프로그래밍 Parallel Programming - concurrent_unordered_map 지난 포스팅에 이어 ppl 에서 제공하는 task 들을 취소할 수 있는 방법을 알..

nanze.tistory.com

오늘은 이전 정리에서 알아본 cacellation_token 의 특성을 알아보자.

concurrency::cancellation_token 특성

우선 task 클래스의 then 함수를 이용하여 task를 엮을 때 두 가지 방법이 있다. 

첫째 then 인자로 이전 task 의 리턴 타입을 파라미터 형태로 전달하는 방식과 이전 task 의 형태로 전달하는 방식이다. 

//값의 형태로 연결
auto task1 = create_task([]()-> int {   
    });
auto task2 = task1.then([](int p){
    });
    
//task 형태로 연결
auto task1 = create_task([]()-> int {
    });
auto task2 = task1.then([](task<int> t){
    });

위 두가지 방식 중 값의 형태로 task를 연결 시, 이전 task의 취소는 다음 연결된 task 까지 모두 취소된다. 

다음 코드를 보자. 

#include <ppl.h>
#include <ppltasks.h>
#include <iostream>

using namespace std;

int main()
{
    auto task = concurrency::create_task( [&]()->int
        {
            concurrency::cancel_current_task();
        }
    );
    
    auto task2 = task.then([](int i){
            wcout << L"task2 reached." << endl;
        }
    );
    
    try{
        task2.get();
    }catch(const concurrency::task_canceled& e){
        wcout << L"task canceled." << endl;
    }
    
    concurrency::task_status st = task2.wait();
    
    switch(st){
        case concurrency::task_status::canceled :
        wcout << L"Task2 canceled." << endl;
        break;
        case  concurrency::task_status::completed :
        wcout << L"Task2 completed." << endl;
        break;
    }
    
    return 0;
}

위 코드를 보면 task 를 수행하자마자 작업을 취소하고 있다. task2 는 값의 형태로 then 을 이용하여 연결되었기 때문에 task2 도 취소에 영향을 받는다.

아래 task 형태의 연결은 결과가 다르다.

#include <ppl.h>
#include <ppltasks.h>
#include <iostream>

using namespace std;

int main()
{
    auto task = concurrency::create_task( [&]()->int
        {
            concurrency::cancel_current_task();
        }
    , token);
    
    auto task2 = task.then([](concurrency::task<int> t){
            wcout << L"task2 reached." << endl;
        }
    );
    
    try{
        task2.get();
    }catch(const concurrency::task_canceled& e){
        wcout << L"task canceled." << endl;
    }
    
    concurrency::task_status st = task2.wait();
    
    switch(st){
        case concurrency::task_status::canceled :
        wcout << L"Task2 canceled." << endl;
        break;
        case  concurrency::task_status::completed :
        wcout << L"Task2 completed." << endl;
        break;
    }
    
    return 0;
}

위 코드는 then 을 이용하여 task 와 task2 연길 시 task 형태로 연결하고 있다. 그렇기 때문에 이전 task 수행 취소와 상관없이 task2는 정상적으로 진행되는 것을 확인할 수 있다.

task의 then() 함수 이용 시, 연계 방식에 따라 작업의 처리가 달라지는 것을 유념해야겠다.

 

반응형