Asynchronous Agents Library – agent. 1 ( 상태 )
작성자: 임준환( mumbi at daum dot net )
Agent 란 무엇인가
개념
Agent 는 사전적 의미로 동작이나 행위를 행하는 사람이나 사물이라는 뜻을 가지고 있습니다. 그 말 그대로 Asynchronous Agents Library( 이하 AAL ) 의 agent 는 어떤 행위를 하는 객체를 나타냅니다.
지난 글에서 AAL 이 actor-based programming 이라고 언급한 적이 있습니다. 여기에서 actor 가 바로 agent 를 일컫습니다.
이해를 돕기 위해 비유를 하자면 agent 는 하나의 작업이라고 생각해도 좋습니다. 그런데 이 작업은 단순히 한 번 처리되는 작업을 말하는 것이 아니라, 어떤 책임이나 역할을 하는 작업입니다. 우리는 멀티 스레드 프로그래밍을 할 때, 이런 개념을 worker 라고 말하기도 합니다.
예를 들어, 네트워크 프로그래밍을 할 때, 소켓에 연결 요청을 기다리고 요청이 들어오면 연결해주는 역할을 하는 스레드가 필요합니다. 이 스레드는 어떤 책임이나 역할을 하는 작업을 가지고 있습니다. 이 스레드를 객체로 표현하면 agent 라고 할 수 있습니다.
클래스
실제 개발 시 필요한 agent 클래스는 Concurrency 네임스페이스 안에 존재하고, agents.h 파일 안에 정의되어 있습니다.
agent 클래스는 추상 클래스로 agent 로 만들 클래스가 상속해야 합니다. agent 클래스의 추상 메소드는 void run() 이고, 반드시 구현해야 합니다.
- 예
#include <iostream> #include <agents.h> using namespace std; using namespace Concurrency; class TestAgent : public agent { protected: void run() { wcout << L"running.." << endl; this->done(); } };
[ 코드1. agent 상속 예 ]
agent 의 상태
agent 는 비 동기 처리를 목적으로 하기 때문에, 내부적으로 스레드를 사용할 수 밖에 없습니다. agent 의 상태란 agent 의 작업을 처리하는 스레드의 상태라고 볼 수 있습니다.
agent 는 생명 주기를 갖는데, 이 주기는 상태로 표현됩니다.
[ 그림1. agent 생명 주기 ]
처음 agent 상태는 크게 초기 상태, 활성화 상태, 종료 상태로 나눌 수 있습니다. agent 객체를 생성하면 그 agent 는 초기 상태인 created 상태가 됩니다. start() 를 호출하면 Concurrency Runtime 에 의해 해당 agent 가 스케줄 되고 runnable 상태가 됩니다.
created 나 runnable 상태에서 cancel() 을 호출하여 작업을 취소하면 canceled 상태가 되는데 이는 종료 상태 중 하나입니다.
위의 그림에서 점선으로 표시된 run() 은 우리가 명시적으로 호출하는 것이 아니라 runnable 상태인 agent 를 Concurrency Runtime 이 호출하는 것을 의미합니다. run() 이 호출되면 활성화 상태인 started 상태가 됩니다.
만약 모든 작업의 수행이 완료되었으면 done() 함수를 호출하여 종료 상태인 done 상태로 바꾸어야 합니다. 동기화를 위한 wait() 등의 함수는 해당 agent 가 종료 상태 즉, done 이나 canceled 상태가 되어야 반환됩니다.
agent 생명 주기에서 가장 중요한 것은 순환되지 않는다는 것입니다. 즉, 되돌아 갈 수 없습니다. 한 번 종료 상태를 갖은 agent 객체는 이미 쓸모 없는 객체가 되고 재사용할 수 없습니다. 그러므로 해당 작업을 다시 수행하기 위해서는 새로운 agent 객체를 생성해야 합니다.
다음은 각 상태에 대한 정의입니다.
agent 상태 | 설명 |
agent_created | agent 가 아직 스케줄 되지 않음. |
agent_runnable | Concurrency Runtime 이 agent 를 스케줄 하고 있음. |
agent_started | agent 가 실행 중임. |
agent_done | agent 의 작업이 완료됨. |
agent_canceled | agent 가 실행 되기 전에 취소됨. |
[ 표1. agent status ]
이 상태들은 status() 메소드로 알아 낼 수 있습니다. status() 는 동기화되기 때문에 정확한 상태를 반환하지만, 그 상태가 현재의 상태라고 보장할 수 없습니다. 왜냐하면 status() 가 반환된 직 후 agent 의 상태가 바뀔 수 있기 때문입니다.
- 예
코드
#include <iostream> #include <agents.h> using namespace std; using namespace Concurrency; class TestAgent : public agent { protected: void run() { wcout << L"running.." << endl; this->done(); } }; void print_agent_status( agent& a ) { wstring status; switch( a.status() ) { case agent_status::agent_created: status = L"agent_created"; break; case agent_status::agent_runnable: status = L"agent_runnable"; break; case agent_status::agent_started: status = L"agent_started"; break; case agent_status::agent_done: status = L"agent_done"; break; case agent_status::agent_canceled: status = L"agent_canceled"; break; } wcout << status.c_str() << endl; } int main() { TestAgent testAgent; print_agent_status( testAgent ); testAgent.start(); for( int i = 0; i < 10; ++i ) { print_agent_status( testAgent ); } agent::wait( &testAgent ); print_agent_status( testAgent ); }
[ 코드2. agent 생명 주기 ]
실행 결과
[ 그림2. 코드2 실행 결과 ]
마치는 글
이번 글에서는 agent 의 개념과 클래스, 그리고 상태에 대해서 알아보았습니다. agent 를 사용하기 위해서는 조금 더 알아야 할 것들이 있습니다.
조금 더 알아야 할 내용들은 다음 글에 작성해 보도록 하겠습니다.
참고
- 그림1. agent 생명 주기 - http://i.msdn.microsoft.com/dynimg/IC338844.png
'VC++ 10 Concurrency Runtime' 카테고리의 다른 글
Asynchronous Agents Library - message 전달 함수. 1 ( 전송 ) (0) | 2010.06.26 |
---|---|
Asynchronous Agents Library – agent. 2 ( 기능 ) (0) | 2010.06.13 |
Asynchronous Agents Library 소개 (0) | 2010.05.29 |
Concurrency Runtime(ConcRT)의 디버그 모드에서 메모리 leak 문제 (5) | 2010.04.19 |
Parallel Patterns Library(PPL) - concurrent_queue - 2 (2) | 2010.01.16 |