프로그래밍/Parallel Programming

병렬 프로그래밍 Parallel Programming - task cancel

nanze 2022. 1. 5. 16:00
반응형

이전 정리글은

2022.01.05 - [프로그래밍/Parallel Programming] - 병렬 프로그래밍 Parallel Programming - cancellation_token 특성

 

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

이전 정리글 2022.01.03 - [프로그래밍/Parallel Programming] - 병렬 프로그래밍 Parallel Programming - cancellation_token 병렬 프로그래밍 Parallel Programming - cancellation_token 이전 정리글은 2022.01..

nanze.tistory.com

이번 정리에는 cancellation_token 아 아닌 task 클래스 또는 task_group 클래스의 cancel 함수를 통한 작업 취소를 정리해보자.

cancel 함수를 호출하였다고 해당 task 를 종료시키는 것이 아니고 취소 요청이므로 task 내부에서 취소되었는지 폴링해야 한다. 

cancel(), is_canceling()

코드를 보자. 

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

using namespace std;
using namespace concurrency;

bool doWork(int n){
    if(n == 100) return false;
    return true;
}

int main()
{
    structured_task_group tgrp;
    
    auto task1 = make_task(
        [&]{
            for(int i=0;i<1000;i++){
                bool b = doWork(i);
                if(!b){
                    wcout << L"try to cancel task group." << endl;
                    tgrp.cancel();
                    break;
                }
            }
        }
    );
    
    auto task2 = make_task(
        [&]{
            for(int i=0;i<1000000;i++){
                if(i% 100 ==0){
                    if(tgrp.is_canceling()){
                        wcout << L"task group was canceled." << endl;
                        break;
                    }
                }
            }
        }
    );
    
    tgrp.run(task1);
    tgrp.run(task2);
    
    task_group_status st = tgrp.wait();
    
    switch(st){
        case task_group_status::canceled :
        wcout << L"Task canceled." << endl;
        break;
        case  task_group_status::completed :
        wcout << L"Task completed." << endl;
        break;
    }
    
    return 0;
}

위 코드를 보면 task_group 의 cancel 함수를 이용하여 취소 요청을 하였고 is_canceling() 함수를 이용하여 취소 여부를 폴링하고 있다.

만약 task 바디에서 task_group 변수에 접근할 수 없을 경우 부모 task group 에 취소 요청을 판단하기 위해서는 이전 정리에서와 같이 is_current_task_group_canceling() 함수를 이용하면 된다. 

다음은 Exception 을 이용한 취소 방법을 정리해보자.

 

Exception 

익셉션을 이용한 방법은 task 내부에서 원하는 상황에 익셉션을 발생시키고 그것을 try catch 로 탐지하여 예외처리를 하는 것이다. 음 이것은 개인적으로 생각했을 때 취소의 방식인지 모르겠다. 작업을 취소시킨다 라는 의미보다 말 그대로 예외처리 인것처럼 해석된다.

일단 코드는 다음과 같다.

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

using namespace std;
using namespace concurrency;

bool doWork(int n){
    if(n == 100) return false;
    return true;
}

int main()
{
    structured_task_group tgrp;
    
    auto task1 = make_task(
        [&]{
            for(int i=0;i<1000;i++){
                bool b = doWork(i);
                if(!b){
                    wcout << L"try to cancel task group." << endl;
                    throw exception("task exception occured.");
                }
            }
        }
    );
    
    auto task2 = make_task(
        [&]{
            for(int i=0;i<1000000;i++){
                if(i% 100 ==0){
                    if(tgrp.is_canceling()){
                        wcout << L"task group was canceled." << endl;
                        break;
                    }
                }
            }
        }
    );
    
    tgrp.run(task1);
    tgrp.run(task2);
    
    try{
        tgrp.wait();
    }catch(const exception& e)
    {
        wcout << e.what() << endl;
    }

    return 0;
}

위의 방식은 task2 는 task1에서 익셉션이 발생한 상황인지 모르기에 종료될 때까지 대기가 필요하다. 역시 취소의 동작으로는 보이지 않는다.

개인적으로 task 취소 방식은 token 방식이 제일 마음에 든다. 

 

다음 정리글은

2022.01.05 - [프로그래밍/Parallel Programming] - 병렬 프로그래밍 Parallel Programming - run-with-cancellation-token

 

병렬 프로그래밍 Parallel Programming - run-with-cancellation-token

이전 정리글 2022.01.05 - [프로그래밍/Parallel Programming] - 병렬 프로그래밍 Parallel Programming - task cancel 병렬 프로그래밍 Parallel Programming - task cancel 이전 정리글은 2022.01.05 - [프로그..

nanze.tistory.com

 

반응형