컴퓨터 프로그램 또는 서브루틴재진입성(再進入性, 영어: Reentrancy)이 있으면, 이 서브루틴은 동시에(병렬) 안전하게 실행 가능하다. 즉 재진입이 가능한 루틴은 동시에 접근해도 언제나 같은 실행 결과를 보장한다. 재진입이 가능하려면 함수는 다음 조건을 만족하여야 한다.

  • 정적 (전역) 변수를 사용하면 안 된다.
  • 정적 (전역) 변수의 주소를 반환하면 안 된다.
  • 호출자가 호출 시 제공한 매개변수만으로 동작해야 한다.
  • 싱글턴 객체의 잠금에 의존하면 안 된다.
  • 다른 비-재진입 함수를 호출하면 안 된다.

여러 '사용자/객체/프로세스'와 멀티프로세싱이 대개 재진입 코드의 제어를 복잡하게 만든다. 또한 입출력 코드는 디스크나 터미널과 같은 공유 자원에 의존하고 있기 때문에 보통은 재진입성이 없다.

재진입성은 함수형 프로그래밍의 핵심 개념이다.

예제 편집

다음 C 코드에서 fg 함수는 재진입이 불가능하다.

int g_var = 1;
int f()
{
  g_var = g_var + 2;
  return g_var;
}
int g()
{
  return f() + 2;
}

위 코드에서 f 함수는 전역 변수 g_var에 의존하고 있다. 만약 두 개의 스레드가 이 함수를 실행하여 g_var에 동시에 접근할 경우, 결과는 실행되는 시점에 따라서 바뀌게 된다. 그러므로 f는 재진입성을 가지지 않는다. g 함수는 비-재진입 함수 f를 호출하기 때문에 역시 재진입이 불가능하다.

이 함수를 다음과 같이 고치면 재진입이 가능하다.

int f(int i)
{
  int priv = i;
  priv = priv + 2;
  return priv;
}
int g(int i)
{
  int priv = i;
  return f(priv) + 2;
}

스레드 안전성과 관계 편집

재진입성과 스레드 안전성 양쪽 모두 함수의 자원 접근 방법과 관련이 있는 개념이다. 하지만 둘은 다르다. 재진입의 개념이 함수의 외부 인터페이스에 관계된 것이라면, 스레드 안전성은 함수의 외부 참조가 아닌 단지 함수의 자체 구현에만 관여하기 때문이다.

  • 대부분의 경우에서 비-재진입 함수를 재진입이 가능하도록 만들려면 함수의 호출자가 제공하는 데이터와 같은 외부 인터페이스를 고쳐야 한다.
  • 스레드-안전하지 않은 함수를 스레드-안전하게 고치려면 경합 조건에서 공유 자원을 보호하도록 동기화 코드를 추가시키는 것과 같이 내부 구현만 수정하면 된다.

그러므로 재진입성은 스레드 안전성보다 더 강한 의미를 가진다: 모든 재진입 함수는 스레드-안전하지만, 모든 스레드 함수가 재진입이 가능한 것은 아니다.

참고 편집