REENTRANT... 어떻게 써야 하는지...

MythRab의 이미지

thread에서 REENTRANT라는 것을 정의해 주어야 한다고 하는데요, 어떻게 정의하고 써야하는지 잘 몰라서요. 의미도 잘 모르겠고 :( ...
thread 프로그램에서 stdout 출력이 잘려서 나온다고 하니 어떤 분이 REENTRANT를 빼먹은것이 아니냐고 하네요.
의미와 선언 또는 사용법 알려주시면 감사하겠습니다. 게시판에서 찾아 읽어봐도 무슨 말인지 잘 모르겠네요...

'출력이 잘린다'는 말은 printf("This is a error!!!\n"); 하는 문장이 있다고 가정하면
s a error!!! <- 이런 식으로 출력되는 것입니다.

indizarm의 이미지

gcc -o 아웃풋 source.c -D_REENTRANT -lpthread

What a Cool Days!!!

deisys의 이미지

MythRab wrote:

thread 프로그램에서 stdout 출력이 잘려서 나온다

이건 REENTRANT 가 아니라 스레드 동기화 문제가 아닐까요..?
간단하게 pthread_mutex_* 같은 녀석들을 한번 사용해서 테스트해보시는것도 괜찮을듯 하네요.

bw001730의 이미지

REENTRANT 에 대해서 문서를 여러개 읽어봤는데
구체적으로 설명해 놓은 문서를 찾을 수가 없었습니다.

한가지...제가 알고 있는 것을 말씀드립니다.
다른 분들도 아시는것을 말씀해주시면 저도 공부되겠네요

errno는 전역변수이잔아요
만약 여러 스레드가 동시에 시스템콜호출시 에러가 발생하면
errno값은 마지막에 발생한 에러값만이 저장될 것입니다.
다른 스레드가 perror() 호출하면 잘못된 에러코드를 가질수 있겠지요

그런데 REENTRANT를 define하면
errno전역변수가 스레드 고유의 영역에 저장된다고 합니다.
그래서 각각의 스레드가 자신만의 errno 값을 가질수 있지요
그래서 perror()함수를 어느스레드에서 호출해도 자신의 에러메시지만
나오게 됩니다.

헤더파일 보면 그냥 int errno 가 아니더군요
복잡하고 알수없는 매크로가 정의되어 잇어요

부트노프 저서 포직스 스레드 프로그래밍 책이 있는데요
이 책에 스레드에 대한 많은 내용이 언급되어있습니다. (강추도서)

스레드 고유의 errno값을 사용하는 것은 성능저하가 있답니다.
(있으면 얼마나 있겠냐 하는 생각으로 그냥 사용합니다만 ^^;)
이 책에서는 만약 새로운 API를 만든다면 전역변수 errno에 에러코드를
저장하는 방식을 사용하지 말고
함수가 성공일때는 0을 리턴하고 그렇지 않으면 errno값을 리턴하도록
만들라고 하더군요
대표적인 함수들이 바로
pthread_xxxx () 이런 함수들이죠
if( pthread_create() != 0 )
{ // 에러 처리 }

pthread_xxx 들과 같은 방식의 함수를 만들어쓰라고 하데요

다른 분들의 도움말을 듣고 싶습니다.

bw001730의 이미지

stdout 이 짤린다는 것의 정확한 의미를 모르겠지만...

stdout 의 사용자 공간의
버퍼를 여러스레드가 동시에 접근할수 있을것 같습니다.

보통은 flockfile() 과 funlockfile() 을 이용하면
스트림을 잠글수 있는데요
여러스레드가 동시에 출력하는 것은 사용자가 알아볼수 없기에
의미가 없는 경우가 많습니다.
그래서 stdout을 잠금한 후에 출력하고 stdout을 잠금해제하는
방식으로 하시면 됩니다.
글구..여러스레드가 동시에 출력하는 프로그램에서는
setvbuf()를 이용해서 _IONBF 옵션을 주어 No-Buffering을 해야할 것 같습니다.
setvbuf( stdout, _IONBF); // 인자가 정확하지는 않음.
flockfile( stdout );
printf("hello");
funlockfile(stdout);

흠 ...아는데로 주절거려본다면
putc()나 putchar()같은 것은 출력할때 잠금을 걸고 출력합니다.
만약 putc()를 루프에서 출력한다면
여러번의 잠금을 걸었다 풀었다해야겠지요
이것은 ansi 표준에 그렇게 되어있다던가 그랫답니다.
따라서 출력의 성능을 높이기 위해서는
잠금을 걸지 않는 putc()를 이용해야 하는데
잠금을 걸지 않는 putc()는 putchar_unlocked()입니다.

flock(stdout);
for( i=0;i<100;i++)
putchar_unlocked('a');
funlockfile(stdout);

지금 어이없는 일이 생겨서..이만 마치겠습니다.

yamainu의 이미지

MythRab wrote:

어떤 분이 REENTRANT를 빼먹은것이 아니냐고 하네요.
의미와 선언 또는 사용법 알려주시면 감사하겠습니다.

REENTRANT 알기쉽게 설명된 예...링크입니다.

http://www.pie.pe.kr/wiki/moin.cgi/Reentrant

Programmers never die: They just GOSUB without RETURN.

sunyzero의 이미지

일반적으로 스트리밍 되면 쓰레드는 이를 공유하므로 출력이 될때 버퍼링이나 기타 다른 이유로도 중간에 다른 출력이 끼어들 수 있습니다.

정 출력이 중요하시면 write() 함수로 출력하시기 바랍니다. PIPE_SIZE 까지는 atomic을 보장해주니까요. 스트림의 경우에도 넌 버퍼링의 경우에는 버퍼링을 하지 않으므로 다른 출력이 끼어들기 힘들기는 하지만, 완전하지는 않습니다.

따라서 쓰레드나 혹은 시그널을 사용하는 경우는 버퍼출력은 write()로 하는게 속편합니다.

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

MythRab의 이미지

debug print 라서 출력이 중요하기도 하지만
출력이 잘린뒤에 segmentation fault가 나거든요.
혹시 출력이 잘린게 segmentation fault의 원이이 되는게 아닌가 해서요...

근데, printf를 fprintf(stderr)로 바꾸면 segmentation fault가 안나는 것 같아요.
안나는 것 같다고 말할 수 밖에 없는 것은 한 30번 정도 돌려봐서 fault가 안나도 안난다고는 할 수 없는 일이기에 ㅡㅡ.
여튼 printf 일 때는 평균적으로 8번 정도 실행 시키면 났는데 fprintf로 바꾸고나서 30-40번 해도 안났으니까 안나는 것 같습니다.
printf와 fprintf의 내부 처리 방식이 다른건지.... 잘 모르겠네요...
fprintf 는 자체적으로 lock 기능이 있는건지...

Heading, heading again, again, ... ㅜㅜ 피난다

simpid의 이미지

deisys wrote:
MythRab wrote:

thread 프로그램에서 stdout 출력이 잘려서 나온다

이건 REENTRANT 가 아니라 스레드 동기화 문제가 아닐까요..?
간단하게 pthread_mutex_* 같은 녀석들을 한번 사용해서 테스트해보시는것도 괜찮을듯 하네요.

쓰레드에서 전역변수를 사용하면 당연히 안되는거죠.

런타임라이브러리(리눅스에서도 이렇게 부르나요?)의 경우 전역변수를 사용하는 버젼과 사용하지 않는 버젼이 있습니다.

멀티쓰레딩을 사용하려면 전역변수를 사용하지 않는 버젼을 사용해야 합니다.

REENTRANT란 것을 우리 말로 "재진입" 이라고 하는것 같던데...
하나의 펑션이 실행되고 있는 동안 다시 실행되는걸 의미합니다.
다중 쓰레딩의 경우가 하나의 코드가 여러개의 쓰레드에 의해 실행되니까 REENTRANT가 지원되도록 프로그래밍을 해야 합니다.

댓글 달기

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