보호 오브젝트

보호 오브젝트는 몇몇 활성 오브젝트나 태스크가 공유하는 데이터를 캡슐화합니다. 이 오브젝트는 자체의 고유 스레드를 소유하지 않지만 다양한 스레드의 호출을 동기화할 수 있습니다.

보호되는 오퍼레이션을 보호 오퍼레이션이라고 합니다. 보호 오퍼레이션은 상호 배제를 시행해야 할 만큼 충분히 중요한 것으로 간주됩니다. 보호 오브젝트는 하나 이상의 보호 오퍼레이션을 소유하는 오브젝트입니다.

보호 오브젝트를 구현하기 위한 한 가지 방법은 오브젝트에 뮤텍스를 제공하여, 보호되도록 명시적으로 설정된 모든 오퍼레이션이 오퍼레이션 시작 시 뮤텍스를 잠그고 종료 시 해제하도록 하는 것입니다.

보호 오브젝트의 구조에 RiCMonitor 멤버가 추가됩니다. 예를 들면, 다음과 같습니다.

typedef struct A A;
struct A {
    RiCMonitor ric_monitor;
    /* other members of A */
};

RiCMonitorIBM® Rational® Rhapsody® 프레임워크에 정의된 유형 모니터입니다.

ric_monitor 서브오브젝트는 보호되도록 태그가 지정된 오브젝트의 오퍼레이션에 대해서만 사용됩니다. CG::Operation::Concurrency 특성을 사용하여 보호되도록 오퍼레이션에 태그를 지정할 수 있습니다.

보호 오퍼레이션은 보호 책임이 있는 랩퍼 오퍼레이션 내에서 보호됩니다. 보호 오퍼레이션은 다음과 같이 private 오퍼레이션으로 생성됩니다.

예를 들어, B 오브젝트의 보호 오퍼레이션 increase()에 대해 두 개의 함수가 생성됩니다.

랩퍼 오퍼레이션에 대한 선언은 오브젝트에 대한 스펙 파일에서 생성됩니다.

int B_increase(B* const me, int i);

랩퍼 오퍼레이션 increase()ric_monitor 오브젝트에 대해 잠금을 얻고 보호 오브젝트를 호출한 후 마지막으로 잠금을 해제합니다.

int B_increase(B* const me, int i) {
    int wrapper_return_value;
    RIC_OPERATION_LOCK(&me->ric_monitor);
    wrapper_return_value = B_increase_guarded(me, i);
    RIC_OPERATION_FREE(&me->ric_monitor);
    return wrapper_return_value;
}

랩퍼 함수가 잠금을 얻으면, 보호 오퍼레이션은 보호 상태가 되고 잠금이 해제될 때까지 다른 오브젝트의 액세스 없이 해당되는 중요한 오퍼레이션을 수행할 수 있습니다.

static int B_increase_guarded(B* const me, int i) {
    {
        /*#[ operation increase(int) */
        return i++;
        /*#]*/
    }
}

마찬가지로, 정리를 수행하는 보호 오퍼레이션과 랩퍼 오퍼레이션에 보호 오브젝트에 대한 cleanup 오퍼레이션이 생성됩니다. 예를 들어, 보호 오브젝트 B에 대한 정리는 먼저 B를 잠근 후 실제 정리를 수행하는 cleanup_guarded()를 호출합니다.

void B_Cleanup(B* const me) {
    RIC_OPERATION_LOCK(&me->ric_monitor);
    B_Cleanup_guarded(me);
}
void B_Cleanup_guarded(B* const me) {
    RiCMonitor_cleanup(&me->ric_monitor);
}

또한 lockfree 매크로를 직접 사용하여 랩퍼 오퍼레이션에 필요한 추가 지원을 피할 수 있습니다.


피드백