C언어 저수준/고수준 입출력 문의

livey의 이미지

"저수준 입출력함수는 1바이트 단위로 입출력을 하고 고수준 입출력함수는 버퍼를 통해 출력한다."
버퍼를 사용하므로 고수준 입출력함수가 더 빠르다는건데
이 말의 의미가 정확히 이해가 되지않아서 문의 드립니다.

1. 시스템콜 호출 횟수 차이인가?
예를들어 1000 바이트를 파일에 출력하는 경우.

저수준 입출력은 write 함수를 1000번 호출하고
고수준 입출력은 fwrite 함수를 한번만 호출하여 1000바이트를 출력한다 라고 이해되는데

결국 시스템콜 호출 횟수의 차이때문에 성능 차이가 있는건가요?

2. 시스템콜은 왜 1바이트씩 처리하나?
시스템콜은 버퍼를 거치지않고 파일에 직접 입출력한다라는 의미가
커널 메모리 버퍼도 사용하지 않고 cpu 가 파일에 직접 입출력하기 때문에 1바이트 단위로만 처리한다는건가요?
파일을 열어놓고 1000바이트를 쓰고 파일을 닫으면 시스템콜을 한번만 호출해도되는거 아닌가요?

이런것들을 이해하려면 어떤 내용들을 봐야하는지 궁금하네요

익명 사용자의 이미지

터미널에서,
man 2 write
man 2 read
하시면 함수 원형 보실 수 있어요.
read, write 는 저수준 입출력 함수이고 버퍼를 사용할 수 있습니다. 고수준 입출력 함수들이 저수준의 입출력 함수를 이용하여 만듭니다. 저수준이라고 해서 수준이 떨어지고 안 좋다는 의미가 아닙니다.

http://man7.org/linux/man-pages/man2/write.2.html

익명 사용자의 이미지

그리고 fwrite 는 고수준 입출력 함수가 아닙니다.

익명 사용자의 이미지

그리고 read, write, fwrite 함수는 c 라이브러리 소스코드를 보시면 됩니다. glibc, musl 과 같은 libc 라이브러리 소스코드보시면 됩니다.

익명 사용자의 이미지

그리고 syscall 은 리눅스 또는 FreeBSD 커널 소스 보시면 됩니다. 관련 책도 있을 듯 합니다. 커널 책과 C책 보시면 모든 의문 풀리실 겁니다. 아니면 학원 다니시던가..ㅋㅋ

라스코니의 이미지

요새 I/O 장치는 대부분 내부에 수 ~ 수십 바이트의 버퍼가 있습니다.

"저수준 입출력함수는 1바이트 단위로 입출력을 하고 고수준 입출력함수는 버퍼를 통해 출력한다." 이라는 말이 좀 애매한데, 즉 일반화가 어려운 설명이라고 생각이 되네요. 반드시 시스템콜하고 연관이 될수 없을 것 같습니다. I/O관련 시스템콜이라고 생각하면 리눅스의 read, write가 바로 연상이 되기 때문에 아주 일반화된(구글링해서도 쉽게 파악할 수 있는) 개념으로 접근하게 될겁니다.

위에서 말하는 저수준 입출력 함수는 버퍼를 염두해 두지 않은 그냥 '단순하게' 설계된 코드를 의미하는 것 같고, 고수준 입출력 함수는 반대로 입출력 장치의 버퍼 full/empty를 고려해서 설계되었고 아마도 blocking/non blocking, lock/unlock까지도 고려된 '높은 설계 수준'의 함수일 가능성이 높다고 개인적으로 생각이 됩니다.

jick의 이미지

설명이 대단히 부정확하게 되어 있거나, 중요한 설명이 앞뒤에 있는 걸 자르고 인용했거나 둘 중에 하나인 것 같군요.

일반적으로 저수준 함수라고 1바이트씩 보내지 않습니다. 그렇게 되는 경우는, 예를 들자면 write를 부르면서 진짜로 1바이트씩 1000번을 불렀을 경우죠.

이 경우 커널 시스템콜을 1000번 부르게 되지만, fwrite를 1바이트씩 1000번 부르면 내부적으로 버퍼링을 하기 때문에 한두 번만 커널을 부르게 됩니다.

* 물론 커널 안에서도 또 내부적으로 버퍼링을 하기 때문에 저장장치에 1바이트씩 1000번을 쓰지는 않습니다. 대부분의 저장 장치는 아예 1바이트씩 쓸 수도 없습니다.

댓글 달기

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