reentrant function이 중요하게 되는 경우는 signal handler에서 사용가능하느냐.. 와 multi-thread 환경에서 입니다.
어떤 function이 전역변수를 사용하거나 static 변수를 사용한다고 할때, 한 process가 이 function에 진입하여 실행중에 signal이 발생하고 signal handler에서 다시 이 function에 진입한다면 예기치 않은 결과를 얻을 수 있습니다. 마찬가지로 동일 process의 서로다른 thread가 같은 function에 진입하는 경우도 문제가 될 수 있습니다.
그래서 reentrant function은 (1)전역변수 사용안함 (2)static 변수 사용안함 (3)stack 변수만 사용 으로 보장됩니다.
조금 다른 개념으로 thread-safe function이라는 개념도 있는데, 이는 reentrant function이거나 그렇지 않은 경우라면 mutex등을 사용하여 전역변수에 대한 동시접근을 막아서 multi-thread 환경에서 안전함을 보장합니다.
thread-safe function이지만 reentrant function이 아닌 경우라면 signal handler에서의 사용은 금지됩니다.
제가 아는 개념으로만으로 설명했기 때문에 틀린부분이 있을지도 모릅니다. 잘못된 부분이 있다면 지적 바랍니다.
int no_reentrant_counter( int increment)
{
static my_counter=0;
my_counter= mycounter + increment;
return my_counter;
}
int reentrant_counter(int current, int increment)
{
return current;
}
함수 내부 변수를 스태틱으로 사용하면 (또는 외부에 전역변수로 사용하면) 사실 편리할 때가 많습니다.
하지만 여러 함수에서 동시에 부르는 (스케줄링에 따라 말이죠) 상황이면 결과가 틀릴 수가 있습니다.
예를 들면 쓰레드 프로그램에서 no_reentrant_counter(1)을 두부분이 사용한다 치면
한부분에서 호출하고 우연히 함수콜 한 다음에 블럭 되어버려서 다른 부분에서 호출하는 부분으로 넘어갈 수도 있습니다.
그당시 my_counter가 10이었다면
(1)번 (2)번이 부른다 치면
* (1) -> no_reentrant 호출
* my_counter= mycounter + 1; 수행도중
>> mycounter+1=11로 계산했고 막 mycounter에 11을 넣으려다 블럭됨 (한줄에 썼지만 몇단계로 나뉘어 실행되죠. 값 읽어오고, 계산하고, 결과 저장하고)
@ (2) -> no_reentrant 호출하였음
@ 아직 my_counter를 11로 못 바꾼 상태이므로 10이었던 것으로 계산해서
@ my_counter= 10+1; ===>11
@ my_counter <=11 후 리턴
* (1)로 다시 돌아가서
* 아까 하던 일 마저하기 (my_counter에 11 넣기)
결국 최종값은 11이 되죠. 두번 호출했으니 12가 되어야 하는데 말이죠.
그래서 쓰레드 돌리며 값을 바꾸는 것과 같이 동기화가 필요한 데에서는 reentrant함수를 사용해야 합니다.
ps. 사실 예로 든게 아주 적절하진 않습니다. reentrant_counter도 저렇게는 써봤자 mutex나 semaphore를 써야 되지만.. 어쨌든 reentrant하지 않으면 결과 값이 이상해 지는 경우도 있구나 하고 생각하시면 됩니다.
꼭 reentrant 해야 하는 함수로 printf가 있죠. 여러 곳에서 동시에 호출하는 데 내부 스태틱 변수 같은 것을 쓴다 치면.. 대란이 일어나겠죠.
간단하게 제가 알고 있는 개념만 말씀드립니다.reentrant f
간단하게 제가 알고 있는 개념만 말씀드립니다.
reentrant function이 중요하게 되는 경우는 signal handler에서 사용가능하느냐.. 와 multi-thread 환경에서 입니다.
어떤 function이 전역변수를 사용하거나 static 변수를 사용한다고 할때, 한 process가 이 function에 진입하여 실행중에 signal이 발생하고 signal handler에서 다시 이 function에 진입한다면 예기치 않은 결과를 얻을 수 있습니다. 마찬가지로 동일 process의 서로다른 thread가 같은 function에 진입하는 경우도 문제가 될 수 있습니다.
그래서 reentrant function은 (1)전역변수 사용안함 (2)static 변수 사용안함 (3)stack 변수만 사용 으로 보장됩니다.
조금 다른 개념으로 thread-safe function이라는 개념도 있는데, 이는 reentrant function이거나 그렇지 않은 경우라면 mutex등을 사용하여 전역변수에 대한 동시접근을 막아서 multi-thread 환경에서 안전함을 보장합니다.
thread-safe function이지만 reentrant function이 아닌 경우라면 signal handler에서의 사용은 금지됩니다.
제가 아는 개념으로만으로 설명했기 때문에 틀린부분이 있을지도 모릅니다. 잘못된 부분이 있다면 지적 바랍니다.
우리 모두 리얼리스트가 되자. 그러나 가슴에 이룰 수 없는 꿈을 가지자
너무 겸손하시군요. 말씀하신 것이 맞습니다.예를 들면[co
너무 겸손하시군요. 말씀하신 것이 맞습니다.
예를 들면
함수 내부 변수를 스태틱으로 사용하면 (또는 외부에 전역변수로 사용하면) 사실 편리할 때가 많습니다.
하지만 여러 함수에서 동시에 부르는 (스케줄링에 따라 말이죠) 상황이면 결과가 틀릴 수가 있습니다.
예를 들면 쓰레드 프로그램에서 no_reentrant_counter(1)을 두부분이 사용한다 치면
한부분에서 호출하고 우연히 함수콜 한 다음에 블럭 되어버려서 다른 부분에서 호출하는 부분으로 넘어갈 수도 있습니다.
그당시 my_counter가 10이었다면
(1)번 (2)번이 부른다 치면
* (1) -> no_reentrant 호출
* my_counter= mycounter + 1; 수행도중
>> mycounter+1=11로 계산했고 막 mycounter에 11을 넣으려다 블럭됨 (한줄에 썼지만 몇단계로 나뉘어 실행되죠. 값 읽어오고, 계산하고, 결과 저장하고)
@ (2) -> no_reentrant 호출하였음
@ 아직 my_counter를 11로 못 바꾼 상태이므로 10이었던 것으로 계산해서
@ my_counter= 10+1; ===>11
@ my_counter <=11 후 리턴
* (1)로 다시 돌아가서
* 아까 하던 일 마저하기 (my_counter에 11 넣기)
결국 최종값은 11이 되죠. 두번 호출했으니 12가 되어야 하는데 말이죠.
그래서 쓰레드 돌리며 값을 바꾸는 것과 같이 동기화가 필요한 데에서는 reentrant함수를 사용해야 합니다.
ps. 사실 예로 든게 아주 적절하진 않습니다. reentrant_counter도 저렇게는 써봤자 mutex나 semaphore를 써야 되지만.. 어쨌든 reentrant하지 않으면 결과 값이 이상해 지는 경우도 있구나 하고 생각하시면 됩니다.
꼭 reentrant 해야 하는 함수로 printf가 있죠. 여러 곳에서 동시에 호출하는 데 내부 스태틱 변수 같은 것을 쓴다 치면.. 대란이 일어나겠죠.
rommance.net
댓글 달기