Main Content

parfeval Future 쿼리 및 취소하기

parfeval 또는 parfevalOnAll을 사용하여 백그라운드에서 계산을 실행하는 경우 Future라는 객체를 만듭니다. Future의 State 속성을 사용하여 Future가 실행 중인지, 대기 중인지 또는 완료되었는지 여부를 확인할 수 있습니다. 병렬 풀의 FevalQueue 속성을 사용하여 실행 중인 Future 및 대기 중인 Future에 액세스할 수도 있습니다. Future를 취소하려면 cancel 함수를 사용할 수 있습니다. 이 예제에서는 다음을 수행합니다.

  • cancel을 사용하여 Future를 직접 취소합니다.

  • 완료된 Future에 대해 완료 오류가 있는지 검사합니다.

  • FevalQueue 속성을 사용하여 Future에 액세스합니다.

대기열에 작업 추가하기

두 개의 워커가 있는 병렬 풀 p를 만듭니다.

p = parpool(2);
Starting parallel pool (parpool) using the 'Processes' profile ...
Connected to parallel pool with 2 workers.

parfeval을 사용하여 백그라운드에서 계산을 실행하는 경우, 이 함수는 각 계산에 대한 Future를 만들고 이를 풀 대기열에 추가합니다. 워커가 유휴 상태가 될 때까지 태스크는 대기열에 남아 있습니다. 워커가 유휴 상태가 되었을 때 대기열이 비어 있지 않으면 워커가 태스크를 계산하기 시작합니다. 워커가 태스크를 완료하면 태스크가 대기열에서 제거되고 워커는 유휴 상태가 됩니다.

효율성을 위해서 Future 객체로 구성된 배열을 사전할당합니다. parfeval을 사용하여 워커가 함수 pause를 백그라운드에서 실행하도록 지시합니다. 세 번째 Future에는 인수 1을 사용하고, 나머지 모든 Future에는 인수 Inf를 사용합니다.

f(1:5) = parallel.FevalFuture;
for n = 1:5
    if n == 3
        f(n) = parfeval(@pause,0,1);
    else
        f(n) = parfeval(@pause,0,Inf);
    end
end

사용되는 parfeval 각각은 워커에서 함수가 실행되는 것을 나타내는 Future 객체를 반환합니다. 세 번째 Future를 제외하면, 모든 Future를 계산하는 데에는 무한대의 시간이 걸릴 것입니다. parfeval(@pause,0,Inf)로 생성된 Future는 대기열의 진행을 느리게 할 수 있는 Future의 극단적인 사례입니다.

직접 Future 취소하기

State 속성을 사용하여 Future의 상태를 가져올 수 있습니다. f에 있는 각 Future의 상태로 구성된 셀형 배열을 만듭니다.

{f.State}
ans = 1×5 cell
    {'running'}    {'running'}    {'queued'}    {'queued'}    {'queued'}

세 번째를 제외한 모든 태스크는 계속 일시 중지 상태입니다.

cancel을 사용하여 두 번째 Future를 직접 취소합니다.

cancel(f(2));
{f.State}
ans = 1×5 cell
    {'running'}    {'finished'}    {'queued'}    {'queued'}    {'queued'}

두 번째 Future를 취소한 후에 세 번째 Future가 실행됩니다. 세 번째 Future가 완료될 때까지 기다린 후 상태를 다시 검사합니다.

wait(f(3));
{f.State}
ans = 1×5 cell
    {'running'}    {'finished'}    {'finished'}    {'running'}    {'queued'}

이제 세 번째 Future의 상태가 'finished'로 바뀌었습니다.

완료 오류 검사하기

Future가 완료되면 State 속성이 'finished'로 바뀝니다. 취소된 Future와 정상적으로 완료된 Future를 구별하려면 Error 속성을 사용하십시오.

fprintf("f(2): %s\n", f(2).Error.message)
f(2): Execution of the future was cancelled.
fprintf("f(3): %s\n", f(3).Error.message)
f(3): 

메시지 속성에 나타난 대로 이 코드는 두 번째 Future를 취소합니다. message 속성에 언급된 대로 두 번째 Future가 취소되었습니다. 세 번째 Future는 오류 없이 완료되므로 오류 메시지가 없습니다.

풀 대기열에 있는 Future 취소하기

FevalQueue 속성을 사용하여 풀 대기열에 있는 Future에 액세스할 수 있습니다.

p.FevalQueue
ans = 
 FevalQueue with properties: 

        QueuedFutures: [1x1 parallel.FevalFuture]
       RunningFutures: [2x1 parallel.FevalFuture]

대기열은 두 속성 RunningFuturesQueuedFutures를 갖습니다. RunningFutures 속성은 현재 실행 중인 태스크에 대응하는 Future로 구성된 배열입니다.

disp(p.FevalQueue.RunningFutures)
 2x1 FevalFuture array:
 
         ID              State  FinishDateTime  Function  Error
       --------------------------------------------------------
    1    22            running                    @pause       
    2    25            running                    @pause       

QueuedFutures 속성은 현재 대기 중이며 실행되고 있지 않은 태스크에 대응하는 Future로 구성된 배열입니다.

disp(p.FevalQueue.QueuedFutures)
 FevalFuture with properties: 

                   ID: 26
             Function: @pause
       CreateDateTime: 24-Oct-2023 17:28:51
        StartDateTime: 
      RunningDuration: 0 days 0h 0m 0s
                State: queued
                Error: none

하나의 Future만 취소하거나 Future로 구성된 배열을 취소할 수 있습니다. QueuedFutures의 모든 Future를 취소합니다.

cancel(p.FevalQueue.QueuedFutures);
{f.State}
ans = 1×5 cell
    {'running'}    {'finished'}    {'finished'}    {'running'}    {'finished'}

f가 최신순으로 정렬되어 있는지에 상관없이 RunningFuturesQueuedFutures는 최신 항목부터 오래된 항목의 순서로 정렬됩니다. 각 Future는 클라이언트의 수명 동안 고유한 ID 속성을 가집니다. f에 있는 각 Future의 ID 속성을 확인합니다.

disp(f)
 1x5 FevalFuture array:
 
         ID              State        FinishDateTime  Function  Error
       --------------------------------------------------------------
    1    22            running                          @pause       
    2    23  finished (unread)  24-Oct-2023 17:29:16    @pause  Error
    3    24  finished (unread)  24-Oct-2023 17:29:17    @pause       
    4    25            running                          @pause       
    5    26  finished (unread)  24-Oct-2023 17:29:52    @pause  Error

이 결과를 각 RunningFuturesID 속성과 비교합니다.

for j = 1:length(p.FevalQueue.RunningFutures)
    rf = p.FevalQueue.RunningFutures(j);
    fprintf("p.FevalQueue.RunningFutures(%i): ID = %i\n", j, rf.ID)
end
p.FevalQueue.RunningFutures(1): ID = 22
p.FevalQueue.RunningFutures(2): ID = 25

여기서, RunningFuturesf(1)f(4)를 포함하는 배열입니다. RunningFutures(2)를 취소하면 네 번째 Future f(4)가 취소됩니다.

작업 공간에서 Future를 사용할 수 없는 경우도 있습니다. 예를 들어, 작업이 완료되기 전에 동일한 코드 부분을 두 번 실행하거나, 함수에서 parfeval을 사용하는 경우가 이에 해당합니다. 작업 공간에서 사용할 수 없는 Future를 취소할 수도 있습니다.

작업 공간에서 f를 지웁니다.

clear f

RunningFuturesQueuedFutures를 사용하여 아직 완료되지 않은 Future에 액세스할 수 있습니다. RunningFutures를 사용하여 f(4)를 취소합니다.

rf2 = p.FevalQueue.RunningFutures(2);
cancel(rf2)
rf2.State
ans = 
'finished'

대기열에 아직 남아 있는 모든 Future를 취소하려면 다음 코드를 사용합니다.

cancel(p.FevalQueue.QueuedFutures);
cancel(p.FevalQueue.RunningFutures);