Computer >> 컴퓨터 >  >> 프로그래밍 >> C++

C/C++ 재진입 함수(Reentrant Function)란 무엇이고, 어떤 조건을 만족해야 할까?

이번 글에서는 C와 C++에서 말하는 재진입 함수(reentrant function)가 무엇인지 살펴보겠습니다. 어떤 함수가 실행되는 도중에 인터럽트(interrupt)에 의해 중단되더라도, ISR(Interrupt Service Routine, 인터럽트 서비스 루틴)의 처리가 끝난 후 중단된 지점부터 안전하게 작업을 다시 이어갈 수 있다면, 그 함수를 재진입 함수라고 부릅니다.

이러한 재진입 함수는 재귀 호출(recursion), 하드웨어 인터럽트 처리처럼 하나의 함수가 동시에 여러 흐름에서 실행될 수 있는 상황에서 반드시 필요합니다.

재진입 함수가 갖추어야 할 조건

함수가 재진입 가능하려면 일반적으로 다음 세 가지 성질을 만족해야 합니다.

  • 전역 변수(global variable)나 static 변수를 사용하지 않는다. 문법적으로는 사용이 가능하지만 권장되지 않습니다. 인터럽트가 발생하는 사이에 전역 변수의 값이 변경될 수 있고, 그렇게 되면 ISR에서 복귀한 뒤 함수는 기대했던 것과 다른 값을 읽어 결과가 달라질 수 있습니다.

  • 자기 자신의 코드를 수정하지 않는다. 함수의 동작은 프로그램 전체 실행 과정에서 항상 동일하게 유지되어야 합니다. 실행 중에 코드 영역이 바뀌면 재진입 시 잘못된 동작으로 이어질 수 있습니다.

  • 재진입 불가능한(non-reentrant) 다른 함수를 호출하지 않는다. 아무리 자신은 순수하게 작성되었더라도, 내부에서 재진입 불가능한 함수를 호출한다면 그 함수 역시 재진입 함수라고 할 수 없습니다.

재진입 불가능한 함수의 예

int x;
int my_function() {
    return x * 10;
}
int my_second_function() {
    return my_function() * 20;
}

위 두 함수는 모두 재진입 불가능합니다. 첫 번째 함수는 전역 변수 x를 사용하고 있으므로 재진입이 불가능하고, 두 번째 함수는 재진입 불가능한 my_function()을 호출하기 때문에 역시 재진입 함수가 될 수 없습니다.

재진입 가능한 함수의 예

int my_function(int x) {
    return x * 10;
}
int my_second_function(int x) {
    return my_function(x) * 20;
}

반면 위 코드에서는 전역 변수 대신 매개변수로 필요한 값을 전달받도록 수정했습니다. 외부 상태에 의존하지 않고 입력값만으로 결과가 결정되므로, 이제 두 함수는 모두 재진입 가능한 함수입니다.

정리

재진입 함수의 핵심은 외부 상태에 의존하지 않고, 자신의 동작을 변경하지 않으며, 재진입 불가능한 함수를 호출하지 않는 것입니다. 이러한 원칙을 지키면 인터럽트 처리나 멀티스레드 환경에서도 함수를 안전하게 호출할 수 있습니다.