printf와 fprintf의 다른점...

MythRab의 이미지

fprintf는 출력 방향을 정할 수 있고, printf는 stdout으로 출력하는 것 말고요,
printf와 fprintf가 내부적으로 다르게 동작하나요?
thread program에서 printf("...", ..)를 쓰면 fault가 나고 fprintf(stderr, "...", ..)을 쓰면 잘 돌아가서요.
출력 방향이 다른 것 때문인지 아님 다른 무언가가 있는지... 제 지식으로는 감당이 안되네요. ㅡㅡ;;
도움을 바랍니다.

sangwoo의 이미지

보통 printf는 vfprintf의 wrapper로 구현되어 있는 경우가 많습니다.
따라서 결국은 동일한 함수를 호출하게 될 겁니다.
말씀하신 문제는 printf - fprintf 의 차이라기보단, stdout과 stderr의
버퍼링 차이일 것 같습니다. 확실히는 잘 모르겠네요. 어떤 상황인지.. ''a
문제를 조금만 더 자세히 설명해 주시겠습니까?

----
Let's shut up and code.

MythRab의 이미지

printf로 하면 segmentation fault가 나기 전에 출력이 완전히 나오지 않거든요.
출력이 잘려서 나오고 그담에 segmentation fault... ㅡㅡ
출력이 잘려서 나오는거랑 fault랑 상관이 있는지는 잘 모르겠지만 fprintf(stderr, ....)을 쓰면 출력도 완전히 나오고 fault도 안나서 말이죠.
printf 때문에 fault 나는지는 정확하지 않습니다.

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

chunsj의 이미지

하나는 stdout, 하나는 stderr이니 그럴 수 밖에요.

MythRab wrote:
printf로 하면 segmentation fault가 나기 전에 출력이 완전히 나오지 않거든요.
출력이 잘려서 나오고 그담에 segmentation fault... ㅡㅡ
출력이 잘려서 나오는거랑 fault랑 상관이 있는지는 잘 모르겠지만 fprintf(stderr, ....)을 쓰면 출력도 완전히 나오고 fault도 안나서 말이죠.
printf 때문에 fault 나는지는 정확하지 않습니다.
최종호의 이미지

chunsj wrote:
하나는 stdout, 하나는 stderr이니 그럴 수 밖에요.

MythRab wrote:
printf로 하면 segmentation fault가 나기 전에 출력이 완전히 나오지 않거든요.
출력이 잘려서 나오고 그담에 segmentation fault... ㅡㅡ
출력이 잘려서 나오는거랑 fault랑 상관이 있는지는 잘 모르겠지만 fprintf(stderr, ....)을 쓰면 출력도 완전히 나오고 fault도 안나서 말이죠.
printf 때문에 fault 나는지는 정확하지 않습니다.

stdout과 stderr 차이 때문에 문제가 발생한다는 건 좀 이상하네요.
간단한 코드이면 한번 올려봐 주세요.
의외로 딴 곳에서 발생한 문제일 수 있을테니까요.

mrmirang의 이미지

fflush(stdout);
하시면 버퍼에 있던 데이터들이 좍 나옵니다.
man fflush

chunsj의 이미지

stderr은 바로 바로 그 내용을 출력합니다만 stdout은 버퍼링을 합니다.
같은 효과를 내고 싶으면 바로바로 fflush(stdout)을 하세요.

최종호 wrote:
chunsj wrote:
하나는 stdout, 하나는 stderr이니 그럴 수 밖에요.

MythRab wrote:
printf로 하면 segmentation fault가 나기 전에 출력이 완전히 나오지 않거든요.
출력이 잘려서 나오고 그담에 segmentation fault... ㅡㅡ
출력이 잘려서 나오는거랑 fault랑 상관이 있는지는 잘 모르겠지만 fprintf(stderr, ....)을 쓰면 출력도 완전히 나오고 fault도 안나서 말이죠.
printf 때문에 fault 나는지는 정확하지 않습니다.

stdout과 stderr 차이 때문에 문제가 발생한다는 건 좀 이상하네요.
간단한 코드이면 한번 올려봐 주세요.
의외로 딴 곳에서 발생한 문제일 수 있을테니까요.

mangg의 이미지

쓰레드를 사용하신다고 하셨으니
각 쓰레들 간의 동기화 문제가 아닐까요?
버퍼링 간의 문제 같은거요.

각 printf 전에 뮤텍스 같은 걸 사용하셔서
한번 확인해 보셨으면 합니다.

-------------------
나는 Copy&Paster 이다. 나의 화려한 기술 조합에 모두들 나를 두려워 한다. 나도 코드 Maker 이고 싶다.

tifler의 이미지

#include <stdarg.h>
#include <stdio.h>

#undef printf

/* Write formatted output to stdout from the format string FORMAT.  */
/* VARARGS1 */
int
printf (const char *format, ...)
{
  va_list arg;
  int done;

  va_start (arg, format);
  done = vfprintf (stdout, format, arg);
  va_end (arg);

  return done;
}

#ifdef USE_IN_LIBIO
# undef _IO_printf
/* This is for libg++.  */
strong_alias (printf, _IO_printf);
#endif
#include <stdarg.h>
#include <stdio.h>


/* Write formatted output to STREAM from the format string FORMAT.  */
/* VARARGS2 */
int
fprintf (FILE *stream, const char *format, ...)
{
  va_list arg;
  int done;

  va_start (arg, format);
  done = vfprintf (stream, format, arg);
  va_end (arg);

  return done;
}
libc_hidden_def (fprintf)

#ifdef USE_IN_LIBIO
/* We define the function with the real name here.  But deep down in
   libio the original function _IO_fprintf is also needed.  So make
   an alias.  */
weak_alias (fprintf, _IO_fprintf)
#endif

/***********************
* while(1) sleep(INFINITE);
***********************/

최종호의 이미지

tifler wrote:
#include <stdarg.h>
#include <stdio.h>

#undef printf

/* Write formatted output to stdout from the format string FORMAT.  */
/* VARARGS1 */
int
printf (const char *format, ...)
{
  va_list arg;
  int done;

  va_start (arg, format);
  done = vfprintf (stdout, format, arg);
  va_end (arg);

  return done;
}

#ifdef USE_IN_LIBIO
# undef _IO_printf
/* This is for libg++.  */
strong_alias (printf, _IO_printf);
#endif
#include <stdarg.h>
#include <stdio.h>


/* Write formatted output to STREAM from the format string FORMAT.  */
/* VARARGS2 */
int
fprintf (FILE *stream, const char *format, ...)
{
  va_list arg;
  int done;

  va_start (arg, format);
  done = vfprintf (stream, format, arg);
  va_end (arg);

  return done;
}
libc_hidden_def (fprintf)

#ifdef USE_IN_LIBIO
/* We define the function with the real name here.  But deep down in
   libio the original function _IO_fprintf is also needed.  So make
   an alias.  */
weak_alias (fprintf, _IO_fprintf)
#endif

printf()와 fprintf() 에서는 별 차이가 없을 것 같은데,
stdout과 stderr 의 차이가 있을지 모르겠습니다.

chunsj님이 올린 글을 보고 테스트 했더니만 정말로
stderr는 버퍼링을 하지 않고 stdout은 라인버퍼링 되었습니다.
둘 다 tty를 사용할 텐데 stderr 는 버퍼링모드를 언버퍼드(?)로
설정하는 것 같습니다. (init이나 getty(?)쪽 소스를 보면 되겠죠?)
(전 둘다 tty를 쓰니까 라인버퍼링 되는 줄 알고 있었습니다.)

printf인 경우에는 버퍼를 사용하다가 동시접근에 의해서
잘못된 영역을 참조해서 문제가 발생할 가능성을 배제할 수 없을텐데
(근데, 메시지가 길지 않고 \n 으로 끝나니까 라인버퍼 모드에서는 금방금방
flush될 것 같은 생각이 드는데요.
흠.. 또 한편으론 버퍼를 계속 이동해가면서 사용하기 때문에 버퍼저쪽 끝에 가서
동시접근이 잘못되면 메시지의 길이에 상관없이 문제가 될 것 같은 생각도 드는군요.)
stderr인 경우에는 아예 버퍼를 사용하지 않으니까 그런 문제가 없는 것이
아닐까요?

stderr 의 버퍼모드를 라인버퍼나 다른 것으로 바꾸거나
stdout의 버퍼모드를 언버퍼드로 변경해서 테스트해 보면 될 듯 한데요.

죽은 프로그램의 코어를 분석해 봐도 될 듯 하고요.
stdout의 _base, _ptr, _cnt 와 같은 버퍼 관련 값들을 살펴보면
도움이 될 것같기도 하고, 아닐 것 같기도 하고요. ㅡ.ㅡ

음.. 그래서 printf() 를 한 후 fflush() 를 하는 것은 죽는 문제를 해결하지
못할 것 같다는데 한표인데, 여러분들은 어떠세요? ㅡ.ㅡ;;
--
쓰고 보니 위에서 sangwoo 님이 벌써 다 하신 얘기군요.. ㅡ.ㅡ;;

댓글 달기

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