시스템 프로그래밍(2)

조권휘·2022년 8월 15일
0

시스템 프로그래밍

목록 보기
2/14
post-thumbnail

Library

  • 재사용 할 수 있도록 function을 저장해둔 set
  • 보통 Linux에는 /lib나 /usr/lib에 위치한다.
  • 필요한 함수가 user program과 link된다.

Library 종류

1) Static Library (*.a)

  • binary program에 직접적으로 연결
  • 모든 program에 각각 연결되어 있는 방식
  • 주로 embedded system에서 사용한다.

2) Shared Library (* .so, *.dll)

  • 공용으로 사용하는 library
  • memory의 낭비를 줄일 수 있다.
  • 'OS'의 도움을 받아서 library로 가는 길을 찾는다.
  • 주로 server system에서 사용한다.

Standard I/O Library

  • <stdio.h> : standard I/O library를 정의한 헤더파일
  • special files → streams → OS에 의해 시작될 때 자동으로 생성
  • stdin, stdout, stderr

왜 standard I/O Library를 사용하는가?

  • OS를 통하지 않고는 system call을 할 수 없기 때문
  • formatting, buffering을 사용하기 위해

File Descriptor

  • OS가 접근할 때 사용하는 것
  • File Descriptor Table에 정수로 저장되어 있다.
  • 0, 1, 2는 각각 stdin, stdout, stderr로 고정되어 있다.
  • 새로운 file이 열리면 3번부터 차례로 부여된다.

Library Buffering

  • buffer : 데이터를 임시 저장할 수 있는 메모리 공간
  • file pointer object를 이용하여 file을 open해서 data를 write하기 전에 임시 저장을 할 수 있는 공간을 마련하고, 그 공간에 저장한 다음 한번에 write하는 방식.
  • system call의 횟수를 줄인다.

### Buffering 방식

1) Full Buffering

  • buffer가 가득 찼을 때만 read/write가 가능
  • system call을 매우 줄일 수 있다.
  • data를 내보내기 힘들다는 단점이 존재
  • fflush()를 이용하여 강제로 data를 내보낼 수 있다.
  • 대부분의 library buffering 방식

2) Line Buffering

  • Console I/O에 사용된다.
  • 줄바꿈(enter 키)이 생겼을 때 동작한다.
  • stdin, stdout이 해당된다.

3) UnBuffering

  • library buffer를 사용하지 않는다.
  • system call을 바로 전달하기 때문에 성능이 나쁘다.
  • 전원이 갑자기 꺼지는 경우와 같을 때 좋다.
  • stderr가 해당된다.

Set Buffering Type

#include <stdio.h>

void setbuf(FILE *stream, char *buf);
// return : None

int setvbuf(FILE *stream, char *buf, int type, size_t size);
// return 0 for success, or nonzero for an error

  • buffering을 지정해준다.

Kernel Buffering

  • user buffer와 별개로 OS 내의 kernel도 data를 모아서 처리하도록 구성한다.
  • disk에 접근을 최소화한다.
  • OS는 disk에서 block 단위로 data를 읽어온다.
  • buffer cache : buffer는 한 방향으로 모아서 보내지만, cache는 중간 매개체 역할을 한다.

I/O buffering & Sync

#include <stdio.h>

int fflush(FILE *stream);
// return 0 for normal, EOF for error
  • buffer가 가득 차지 않아도 library buffer에 있는 것을 kernel로 block 단위만큼 내려준다.
  • kernel까지 내려주지만, sync()를 호출하면 disk까지 간다.

File Open/Reopen

1) fopen

FILE *fopen(const char *filename, const char *type);

  • type : access mode
  • return : 성공 시 열린 file의 file pointer / 실패 시 NULL
  • open file의 개수는 제한이 되어 있다.

2) freopen

File *freopen(const char *filename, const char *type, FILE *stream);
  • type : access mode
  • stream : file pointer
  • return : 성공 시 열린 file의 file pointer / 실패 시 NULL
  • 이전 stream을 그대로 사용하기 때문에 File 이름하고의 관계만 끊어진다.

File Close

int fclose(FILE *stream);
  • open 된 file을 닫는다.
  • process가 종료되면 OS가 file descriptor table을 보고 모든 file을 자동적으로 닫는다.

File I/O Functions

size_t fread(void *ptr, size_t size, size_t nitems, FILE *stream)
  • ptr: buffer 주소
  • size: object의 byte수 (전체 size)
  • nitems: object의 수
  • stream: file pointer
  • return : 성공 시 읽은 object의 수 / 실패 시 0
size_t fwrite(void *ptr, size_t size, size_t nitems, FILE *stream)
  • ptr: buffer 주소
  • size: object의 byte수 (전체 size)
  • nitems: object의 수
  • stream: file pointer
  • return : 성공 시 쓴 object의 수 / 실패 시 0

Character Input

int getc(FILE *stream)
int fgetc(FILE *stream)
  • file에 char를 가져온다.
  • return : 성공 시 int type의 char / 실패 시 EOF
int getchar(void)
  • stdin으로부터 char를 가져온다.
  • return : 성공 시 int type의 char / 실패 시 EOF
char *fgets(char *s, int size, FILE *stream)
  • NULL("\O")이 나올 때(줄바꿈)까지 문자열을 가져온다.
  • size : max string size + 1
  • return : 성공 시 string의 address / 실패 시 NULL
char *gets(char *s)
  • stdin에서 NULL("\O")이 나올 때(줄바꿈)까지 문자열을 가져온다.
  • return : 성공 시 string의 address / 실패 시 NULL

Character Output

int putc(int c, FILE *stream),
int fputc(int c, FILE *stream)
  • file에 char를 write한다.
  • return : 성공 시 int type의 char / 실패 시 EOF
int putchar(int c)
  • stdout에 char를 write 한다.
  • return : 성공 시 int type의 char / 실패 시 EOF
int *fputs(const char *s, FILE *stream)
  • NULL("\O")이 나올 때(줄바꿈)까지 문자열을 write한다.
  • return : 성공 시 char의 수 / 실패 시 EOF
char *puts(const char *s)
  • stdout에 NULL("\O")이 나올 때(줄바꿈)까지 문자열을 write한다.
  • return : 성공 시 char의 수 / 실패 시 EOF

File Offset

  • 모든 open file은 file에서 다음 접근 위치를 나타내는 r/w offset을 가진다.
  • read/write는 현재 offset이 위치한 곳에서 일어난다.
  • file이 처음 read/write를 위해 open될 때, offset은 file의 처음에 위치한다.
  • file이 추가를 위해 open 될 때, offset은 file의 끝에 위치한다.
  • read/write가 진행되는 동안, offset은 자동적으로 최신화된다.

File Access

1) Sequential Access (순차접근)

  • 현재 r/w offset에 따라 접근한 뒤 read/write를 진행한다.

2) Random Access

  • 원하는 위치에 r/w offset을 이동시킨 후 read/write를 진행한다.
  • 주로 fseek(), lseek()를 사용한다.
    • fseek() : Library function
    • lseek() : System Call

R/W offset function

int fseek(FILE *stream, long offset, int sopt)]
  • offset을 지정된 위치로 이동
  • stream : file pointer
  • offset : SEEK option에서 떨어진 거리
  • sopt : SEEK option
  • return : 성공 시 0 / 실패 시 -1

SEEK option

  • SEEK_SET : new r/w offset = offset
  • SEEK_CUR : new r/w offset = current_offset+ offset
  • SEEK_END : new r/w offset = EOF+ offset
void rewind(FILE *stream)
  • offset을 맨 처음(시작점)으로 변경
long ftell(FILE *stream)
  • offset의 현재 위치를 return
  • return : 성공 시 현재 offset / 실패 시 -1

I/O Types

1) Unformatted I/O(Binary I/O)

  • 자료형 그 자체를 그대로 저장하거나 읽는 것
  • program만 이해가 가능하다.
  • integer, float, double...

2) Formatted I/O(Text I/O)

  • ASCII 코드 등으로 해석해주는 것
  • 다른 program은 필요 없지만 data 양이 많아진다.
  • %f, %5d, cat file...

Formatted Output

int printf(const char *format,/* args*/ ... )
  • console에 출력
  • return : 성공 시 output length / 실패 시 negative integer
int fprintf(FILE *stream, const char *format,/* args*/ ... )
  • file에 출력
  • return : 성공 시 output length / 실패 시 negative integer
int sprintf(char *s, const char *format,/* args*/ ... )
  • char buf 에 출력
  • return : 성공 시 output length / 실패 시 negative integer

Formatted Input

int scanf(const char *format,... )
  • console에 입력한 것을 읽어들임
  • return : 성공 시 input length / 실패 시 EOF
int fscanf(FILE *stream, const char *format,... )
  • file에 입력한 것을 읽어들임
  • return : 성공 시 input length / 실패 시 EOF integer
int sscanf(char *s, const char *format,... )
  • char buf 안에 있는 것을 읽어들임
  • return : 성공 시 input length / 실패 시 EOF integer

Error Handling

  • 특정 파일에 여러가지 error가 발생 가능하다.
  • error number에 따라 다르게 정의되어 있다.
  • <errno.h> 에 정의된 errno 변수를 통해 알 수 있다.

File error check

int ferror(FILE *stream)
  • error가 발생했을 때 return을 확인
  • return : error가 있으면 errno / error가 없으면 0
int feof(FILE *stream)
  • file의 끝에 도달하였는지 판단
  • return : file의 끝에 도달하지 않았으면 errno / 도달했으면 0
void clearerr(FILE *stream)
  • 현재까지 발생한 error를 clear해준다.
  • 가능하면 사용하지 않는 것이 좋다.
profile
안녕하세요 :) Data/AI 공부 중인 한국외대 컴퓨터공학부 조권휘입니다.

0개의 댓글