reentrant와 thread-safe함수와의 관계...

omando의 이미지

바로 앞에서도 비슷한 질문 올렸는데요.

답변해주신분들께 깊히 감사드립니다.

정확히는 아직도 개념파악이 안되지만 좀은 알것 같기도 하네요
그런데 한가지 의문점이 생기는군요.

그렇다면 reentrant함수와 동기화위한 세마포어,mutex등과의 차이가뭐죠?

이미 라이브러리화 되어 있는 reentrant함수등을 사용시 그런 동기화라직을
고려하지 않더라도 내부적으로 알아서 동기화를 해줄거니까 신경쓰지 말라는건가요?
아니면 reentrant함수라는 것은 반드시 그런 동기화 라직을 고려해서
주위깊게 사용하라는것을 유저에게 알려주기 위한 일반적인 명칭인가요?

그리고 reentrant함수 사용시 -D_REENTRANT를 사용하여 컴파일하여야하는건가요?.. 어떤 함수가 reentrant함수인지 어떻게 알지??????

thread-safe function라는 것은 또 뭐죠?
에고 갈수록 더 복잡해지는군요

혹시 이와 관련된 참고 서적이 있으면 추천좀 해주세요

stoneshim의 이미지

Quote:
이미 라이브러리화 되어 있는 reentrant함수등을 사용시 그런 동기화라직을 고려하지 않더라도 내부적으로 알아서 동기화를 해줄거니까 신경쓰지 말라는건가요? 아니면 reentrant함수라는 것은 반드시 그런 동기화 라직을 고려해서 주위깊게 사용하라는것을 유저에게 알려주기 위한 일반적인 명칭인가요?

reentrant function은 내부에서도 외부에서도 동기화와 관련이 없습니다.
동일 프로세스에서 혹은 여러 thread에서 동시에 접근이 되어도 안전한 function 이지요. reentrant function에 대한 의미와 function 호출시 stack이 생성된다는 것을 생각하시면 이해가 되실 겁니다.

Quote:
그리고 reentrant함수 사용시 -D_REENTRANT를 사용하여 컴파일하여야하는건가요?..

thread library 내부에서 _REENTRANT 를 사용하는 것으로 알고 있습니다.
다른 곳에서도 사용될지 모르고, 안전함을 위해서 명시하시는 것이 좋겠지요?
이 내용은 Linux 뿐 아니라 Solaris에서도 마찬가지 입니다.

Quote:
어떤 함수가 reentrant함수인지 어떻게 알지??????

저도 잘 모르겠습니다. man page에 명시되지 않았다면 대충 느낌으로 짐작하는 수밖에...
하지만 스스로 함수를 작성할 때에는 주의해서 잘 짜야겠지요?

Quote:
thread-safe function라는 것은 또 뭐죠?

thread-safe function 은 말 그대로 multi-thread환경에서 여러 thread가 동시에 동일 함수에 진입했을 때 안전한 function 입니다.

저번에도 말씀드렸듯이 thread-safe function은 reentrant function 이거나, reentrant function이 아니라면 mutex 등으로 전역변수에의 동시 접근을 막아서 여러 thread가 동일 함수에 동시에 진입했을때 안전함을 보장하는 function 입니다.

reentrant function은 내부적으로도 동기화를 위한 locking처리 자체를 하지 않습니다. 동기화 할 필요가 없도록 function을 설계하는 것이지요.

하지만 어쩔수 없이 전역변수를 사용해야 하는 function이 있을 수 있겠지요? 이런 function이라면 여러 thread가 동시에 접근하는 경우에 대비해 전역변수를 사용하는 code 부분을 mutex 등으로 막아서 여러 thread가 동시에 function에 진입할 수는 있으나 동시에 전역변수에 접근하지는 못하도록 합니다.
이런 경우 동일 process/thread context에서 signal이 발생하여 signalhandler에서 이 함수에 다시 진입한다면 dead lock 이 발생할 수 있습니다.
그렇기 때문에 reentrant 하지 않은 thread-safe function은 signal handler에서 사용하지 않습니다.

결국 어떤 function이 reentrant function 이라면 당연히 thread-safe function입니다.
하지만 모든 thread-safe function이 reentrant function 인 것은 아닙니다.

우리 모두 리얼리스트가 되자. 그러나 가슴에 이룰 수 없는 꿈을 가지자

pynoos의 이미지

부언하여 -D_REENTRANT 를 제가 아는 한도에서 설명드리자면,

선언이 되면, 대개의 구현에서..
1.
include 할 때, _r 계열 함수의 선언을 열어 주는(?) 것과

2.
기존 함수 혹은 변수를 reentrant 계열로 재정의해주게 됩니다.

즉, 함수가 두 벌이 존재하고, -D_REENTRANT 에 따라 link 되는 것이 달라지게 됩니다.

그리고, 대개의 구현에서 내부에 static 값이 있는 경우에 대해 pthread_key_create 시리즈 함수를 사용하여 thread 만의 데이터를 핸들링하도록 합니다.

잘못된 내용이 있으시면 지적해주시고, 추가 글 주시길바랍니당.

kslee80의 이미지

gcc 의 스크립트(정확히는 spec 파일)를 대강 본 적이 있는데....
-lpthread 를 gcc 커맨드 라인에 적게 되면
자동으로 -D_REENTRANT 를 추가하는듯 합니다.

charsyam의 이미지

omando wrote:
바로 앞에서도 비슷한 질문 올렸는데요.

답변해주신분들께 깊히 감사드립니다.

정확히는 아직도 개념파악이 안되지만 좀은 알것 같기도 하네요
그런데 한가지 의문점이 생기는군요.

그렇다면 reentrant함수와 동기화위한 세마포어,mutex등과의 차이가뭐죠?

이미 라이브러리화 되어 있는 reentrant함수등을 사용시 그런 동기화라직을
고려하지 않더라도 내부적으로 알아서 동기화를 해줄거니까 신경쓰지 말라는건가요?
아니면 reentrant함수라는 것은 반드시 그런 동기화 라직을 고려해서
주위깊게 사용하라는것을 유저에게 알려주기 위한 일반적인 명칭인가요?

그리고 reentrant함수 사용시 -D_REENTRANT를 사용하여 컴파일하여야하는건가요?.. 어떤 함수가 reentrant함수인지 어떻게 알지??????

thread-safe function라는 것은 또 뭐죠?
에고 갈수록 더 복잡해지는군요

혹시 이와 관련된 참고 서적이 있으면 추천좀 해주세요

간단하게 예를 들자면, strtok 이라는 함수는 내부적으로 static 변수를
이용하여 pointer를 저장하고 있습니다. 그래서 다중 스레드 상황에서
단순히 strtok 함수를 부르게 되면, 각각 부를 때 마다, 이전 값으로
실행이 되 버리게 되므로 이상한 결과가 나오게 됩니다.

<예>
스레드 A
strtok("I am thread-safe"," ");

스레드 B
strtok("I am not thread-safe", " ");

(처음 이후에는 모두 strtok( NULL, " " );을 씁니다.)

ABAB 순으로 계속 일어나면 처음에는

A의 결과로 I 가 나오게 되고 다시 B에서 B의 결과로 I가 나옵니다.

다음에는 A에서 am 이 B 에서는 not 이 나오게 됩니다.

서로 의도했던 I, am, thread-safe , I, am, not, thread-safe가

나오지 않게 됩니다. 스레드-safe 한 함수를 쓰게되면, 위의 결과가

제대로 나오게 됩니다. 동기화 객체를 사용하는 것과는 조금 틀립니다.

동기화 객체는 하나의 스레드 내에 동시에 접근하면 안되는 데이터를

보호하기 위한 것이고, 스레드-safe는 각각 여러개가 동시에 접근해도

원래의 목적대로 진행이 된다는 것입니다. 보통 지역변수를 사용하고,

글로벌 변수나, 스태틱을 안쓰면 스레드-safe 하게 되서 재진입이

가능해집니다. 그럼 고운 하루되시길...

=========================
CharSyam ^^ --- 고운 하루
=========================

stoneshim의 이미지

Quote:
-lpthread 를 gcc 커맨드 라인에 적게 되면
자동으로 -D_REENTRANT 를 추가하는듯 합니다.

-lpthread로 테스트 해보았는데 _REENTRANT가 define되지 않는군요.
혹시 버전상의 문제일지 모르겠군요.

테스트 결과가 저와 다른 분 계신가요?

gcc version 2.95.3 20000503/Linux (prerelease)
Linux 2.4.20 #1 SMP Wed Apr 9 14:32:24 KST 2003 i686 unknown

우리 모두 리얼리스트가 되자. 그러나 가슴에 이룰 수 없는 꿈을 가지자

sunyzero의 이미지

-D_REENTRANT 는 선언해주어야 하는것으로 알고 있습니다. -lpthread는 그냥 pthread library 링킹을 선언해주는 것외에는 아무런것이 없습니다. define과 library 링킹 작업에는 하등의 상관이 없겠죠. 어차피 define은 include시 헤더에 영향을 줄테니까요.

========================================
* The truth will set you free.

댓글 달기

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
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.