reentrant에 대한 고찰....

omando의 이미지

:oops:
스레드관련 부분에 보면 reentrant라는 용어가
자주 나오더군요. 이걸 지원하지 않는 함수를 사용하는경우
스레드끼리의 충돌 발생 가능성이 있다는 의미 같던데
정확하게 무슨 의미인지를 모르겠어요.

여기저기 사이트를 다 뒤지면서
설명한곳을 보았지만 너무 어렵더군요.
제발 좀 명쾌하고 자세히좀 알려주세요.

흑흑흑..

stoneshim의 이미지

간단하게 제가 알고 있는 개념만 말씀드립니다.

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가 있죠. 여러 곳에서 동시에 호출하는 데 내부 스태틱 변수 같은 것을 쓴다 치면.. 대란이 일어나겠죠.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.