- 표준 입출력 함수
> 좋은 이식성, 버퍼링을 통한 성능 향상에 도움
> 버퍼링을 이용하면 모든 상황은 아니지만 전송할 데이터양이 많을수록 성능이 우월
(전송하는 데이터 양, 출력 버퍼로 데이터 이동 횟수)
- 표준 입출력 함수 vs 시스템 함수
> 시스템 함수 read() write()를 이용하면 큰 용량의 파일을 읽을 시 버퍼를 제공 하지 않기 때문에 느리다.
> 표준 입출력 함수 fputs() fgets()는 버퍼를 이용하기 때문에 보다 빠르다
- 표준 입출력 함수 사용에 있어서 불편한 사항
> 양방향 통신이 쉽지 않다
> 상황에 따라서 fflush 함수의 호출이 빈번히 등장할 수 있다.
> 파일 디스크립터를 FILE 구조체의 포인터로 변환해야 한다.
cf. 파일을 읽고 쓰기가 동시에 가능하려면 r+, w+, a+ 모드로 파일을 열어야 함
- 파일 디스크립터 <=> FILE 포인터 변환 함수
> FILE* fdopen(int _FileHandle, const char* _Format);
->파일 디스크립터를 FILE 포인터로 변환하는 함수
> int fileno(FILE* _File);
-> FILE 포인터를 파일 디스크립터로 변환하는 함수
- 입출력 스트림 분리
> TCP 입출력 Routine(코드) 분할
> 읽기모드와 쓰기모드의 FILE 포인터로 분할
- 스트림 분리 이점
> 입력 Routine과 출력 Routine의 독립을 통한 구현의 편의성 증대
> 입력에 상관없이 출력이 가능, 속도의 향상 기대
> FILE 포인터는 읽기모드 쓰기모드로 구분해야 하므로
> 읽기모드와 쓰기모드의 구분을 통한 구현의 편의성 증대
> 입력 버퍼와 출력버퍼를 구분하여 버퍼링 기능 향상
- 스트림 분리 이후 EOF에 대한 문제
> fdopen 함수호출로 만들어진 FILE 포인터 대상으로 Half-close가 잘 진행이 안됨
> FILE 포인터 대상으로 fclose() => 디스크립터가 종료 => 소켓이 완전 종료
> 파일 디스크립터를 복사하여 읽기모드가 가능하도록 해야함
(파일 디스크립터는 입력과 출력이 모두 가능)
- 파일 디스크립터의 복사(Linux)
> int dup(int fildes);
> int dup2(int fildes, int fildes2);
>복사된 파일 디스크립터의 수에 상관없이 EOF의 전송을 동반하는 Half-close를 진행하려면 shutdown()을 호출 해야함
- select() 기반 IO 멀티플렉싱의 불합리한 점
> 함수 호출 이후 항상 등장하는, 모든 파일 디스크립터를 대상으로 하는 반복문
> 호출할 때마다 인자로 관찰 대상에 대한 정보를 매번 운영체제에 전달
->소켓은 운영체제의 관리 대상이므로 운영체제에 의해 기능이 완성
> 해결책 : 운영체제에게 관찰대상에 대한 정보를 딱 한번만 알려주고 관찰 대상의 범위나 내용 변경이 있을 때 변경 사항만 알려줌 => epoll(Linux), IOCP(Windows)
- select() 기반의 장점
> 대부분의 운영체제에서 지원 (리눅스는 epoll, BSD는 kqueue, 솔리리스는 /dev/poll, 윈도우는 IOCP)
> 사용하는 경우
1) 서버의 접속자 수가 많지 않을 경우
2) 다양한 운영체제에서 운영이 가능해야 할 경우
- 쓰레드
> 멀티 프로세스 기반의 단점
-> 프로세스 생성은 부담스러운 작업과정
-> 두 프로세스간 데이터 교환을 위해서 IPC 기법을 적용해야함
-> 초당 적게는 수십 번에서 많게는 수천 번까지 일어나는 'Context Switching'에 따른 부담
> Context Switching
-> 메인메모리에 프로세스 관련 데이터를 전환 하는 것
> 쓰레드 생성 및 컨텍스트 스위칭은 프로세스의 생성 및 컨텍스트 스위칭보다 빠름
> 쓰레드 사이에서의 데이터 교환에는 특별한 기법이 필요치 않음
- 쓰레드와 프로세스의 차이점
> 쓰레드
-> 컨텍스트 스위칭 시 데이터 영역과 힙은 올리고 내릴 필요가 없음
-> 데이터 영역과 힙을 이용해서 데이터 교환이 가능
> 프로세스 : 운영체제 관점에서 별도의 실행 흐름을 구성하는 단위
> 쓰레드 : 프로세스 관점에서 별도의 실행 흐름을 구성하는 단위
- Worker thread 모델
> main()이 관리하는 일꾼의 형태
- 쓰레드 문제와 Critical Section(임계영역)
> 메모리 공간에 동시에 접근시 문제
> 임계영역 : 함수 내에서 둘 이상의 쓰레드가 동시에 실행하면 문제를 일으키는 하나 이상의 문장으로 묶여있는 코드 블록
- 쓰레드 동기화
> 동일한 메모리 영역으로의 동시 접근이 발생하는 상황
> 동일한 메모리 영역에 접근하는 쓰레드의 실행순서를 지정해야 하는 상황
> mutex, semaphore(실행순서 지정 가능)
'programing > Networks' 카테고리의 다른 글
Overlapped IO 모델 (0) | 2015.06.01 |
---|---|
Asynchronous Notification IO 모델 (0) | 2015.05.22 |
멀티 캐스트& 브로드 캐스트 (0) | 2015.05.18 |
입출력 함수 (0) | 2015.05.18 |
IO 멀티플렉싱 기반 서버 (0) | 2015.05.15 |