728x90
간단한 정리
10. 시스템 수준 입출력
- 입출력은 메인메모리와 디스크 드라이브, 터미널, 네트워크 같은 외부 장치들 간에 데이터를 복사하는 작업이다. 입력연산은 입출력 장치에서 메인메모리로 데이터를 복사하고, 출력연산은 데이터를 메모리에서 디바이스로 복사한다.
- 모든 언어의 런타임 시스템은 입출력을 수행하기 위한 고급 기능들을 제공한다.
10.1
- 리눅스에서 파일은 연속된 m개의 바이트다.
- 네트워크, 디스크, 터미널 같은 모든 I/O 디바이스들은 파일로 모델링되며, 모든 입력과 출력은 해당 파일을 읽거나 쓰는 형식으로 수행된다. Unix I/O를 통해 모든 입력과 출력이 통일된 방식으로 수행되게 해준다.
파일열기
- 응용은 I/O 디바이스에 접근하겠다는 의도를 해당 파일을 열겠다고 커널에 요청하는 방법으로 알린다. 커널은 식별자라고 하는 작은 비음수를 리턴하며, 이것은 이후의 파일에 관한 모든 연산에서 이 파일을 나타낸다. 커널은 열린 파일에 관한 모든 정보를 추적한다. 응용은 식별자만을 추적한다.
- 리눅스 쉘이 만든 각 프로세스는 세 개의 열린 파일을 가지고 동작한다. : 표준입력(식별자 0), 표준출력(식별자1), 표준에러(식별자2)
현재 파일 위치의 변경
- 커널은 파일을 열때마다 파일 위치k를 관리하며, 이것은 처음에는 0이다. 파일 위치는 파일의 시작 부분에서부터의 바이트 오프셋이다. 응용프로그램은 seek연산을 수행해서 현재의 파일 위치를 명시적으로 설정할 수 있다.
파일 읽기와 쓰기
- 읽기 연산은 현재 파일 위치 k에서 시작해서 n>0 바이트를 파일에서 메모리로 복사하고 k를 n 증가시킨다. 크기가 m바이트인 파일이 주어졌을 때, k≥m 인 읽기 연산을 수행하면 EOF로 알려진 조건이 발생하며 응용프로그램에서 감지할 수 있다.
- 마찬가지로, 쓰기연산은 현재 파일 위치k에서 시작해서 n>0 바이트를 메모리에서 파일로 복사하고, k를 갱신한다.
파일 닫기
- 응용이 파일 접근을 끝마치면, 커널에 파일을 닫아줄 것을 요청한다. 커널은 파일을 열었을 때 만든 자료구조들을 반환하는 것으로 대응하며, 식별자를 가용식별자 풀로 복원한다. 프로세스가 어떤 이유에서는 종료할 때, 커널은 모든 열려있는 파일들을 닫고, 이들의 메모리 자원을 반환한다.
10.2 파일
- 리눅스 파일은 시스템에서의 역할을 나타내는 타입을 가진다.
- 일반 파일은 임의의 데이터를 포함한다. 응용프로그램은 텍스트 파일과 그외 모든 파일을 포함하는 이진 파일로 파일들을 구분한다. 커널에게는 텍스트나 이진 파일 간에 차이는 없다.
- 디렉토리는 링크들의 배열로 구성되며, 각각의 링크는 파일 이름을 파일로 대응시키며, 이 이름은 또 다른 디렉토리일 수도 있다. .(점 한 개)는 자신의 디렉토리로의 링크고 ..(점 두 개)는 디렉토리 계층구조에서 부모 디렉토리로의 링크이다.
- 소켓은 네트워크 상의 다른 프로세스와 통신하기 위해 사용되는 파일이다.
- 리눅스 커널은 파일들을 루트 디렉토리라고 하는 /(사선)에 연결된 단일 디렉토리 계층구조로 구성된다.
- 쉘은 현재 작업 디렉토리를 cd 명령으로 변경할 수 있다.
10.3 파일 열기와 닫기
- open 함수를 호출해서 기존의 파일을 열거나 새 파일을 생성한다.
open(filename, flag, mode)
- 파일 이름을 파일식별자로 변환하고 식별자 번호를 리턴한다. 리턴된 식별자는 항상 프로세스내에서 현재 열려있지 않은 가장 작은 식별자다.
- flag 인자는 어떻게 프로세스가 파일에 접근하는지를 나타낸다.
- ex) reading only, writing only, reading and writing
- 쓰기 작업을 위한 추가적인 명령을 제공하도록 한 개 이상의 비트 마스크들을 OR 형태로 작성할 수도 있다.
- mode 인자는 새 파일들의 접근 권한 비트들을 명시한다.
- 마지막으로, 프로세스는 오픈한 파일은 close 함수를 호출해서 닫는다.
int close(fd)
- 이미 닫은 파일 식별자를 닫게되면 에러다.
10.4 파일 읽기와 쓰기
- 응용은 read와 write 함수를 호출해서 읽기와 쓰기를 수행한다.
read(fd, *buf, n)
- read 함수는 fd의 현재 파일 위치에서 최대 n바이트를 메모리 위치 buf로 복사한다. 리턴 값-1은 에러를, 0은 EOF를 나타낸다. 그렇지 않으면 리턴 값은 실제로 전송한 바이트 수를 나타낸다.
write(fd, *buf, n)
- write 함수는 메모리위치 buf에서 식별자 fd의 현재 파일 위치로 최대 n바이트를 복사한다.
- 일부 경우에 read와 write는 응용이 요청하는 것보다 더 적은 바이트를 전송한다. 이러한 짧은 카운트는 에러를 나타내는 것은 아니다. 이들은 여러가지 이유로 발생한다.
- EOF를 읽기중에 만났을 때
- 터미널에서 텍스트 줄을 읽을 때
- 네트워크 소켓을 읽거나 쓸 때
10.5 RIO 패키지를 이용한 안정적인 읽기와 쓰기
- Robust I/O은 짧은 카운트를 자동으로 처리한다. RIO 패키지는 짧은 카운트가 발생할 수 있는 네트워크 프로그램 같은 응용에서 편리하고, 안정적이고 효율적인 I/O를 제공한다.
- 버퍼없는 입력 및 출력함수 : 메모리와 파일 사이에 응용 수준의 버퍼링 없이 직접 데이터를 전송한다. 이들은 특히 네트워크에서 바이너리 데이터를 읽고 쓸 때 유용하다.
- 버퍼를 사용하는 입력함수 : 텍스트 라인들과 내용이 응용 수준 버퍼에 캐시되어 있는 파일의 바이너리 데이터를 효율적으로 읽도록 해준다.
- rio_readn은 eof 파일을 만나게 되면 짧은 카운트를 리턴하지만, rio_writen을 짧은 카운트를 리턴하진 않는다.
Buffered I/O
- Buffered I/O RIO에서 버퍼를 관리한다는 의미를 지닌다.
- 보통 프로그램에서는 1개의 글자를 읽는데 1번의 시간(cycle)이 걸린다.
- 예를 들어 hello를 출력하려면 ‘h’,’e’,’l’,’l’,’o’를 각각 따로 출력을 해줘야 한다는 의미로 매우 비효율적이다.
- 이에 대한 해답이 버퍼를 사용하는 읽기 방식인데 Buffered read 이다.
10.6 파일 메타데이터 읽기
- 응용은 파일에 관한 정보를 stat과 fstat함수를 호출해서 가져올 수 있다.
stat(filename, *buf)
- stat 함수는 파일 이름을 입력받아 stat 구조체의 멤버들을 채워준다.
fstat(fd, *buf)
10.7 디렉토리 내용읽기
- 응용 readdir 계열의 함수를 이용해 디렉토리의 내용을 읽을 수 있다.
10.8 파일 공유
- 리눅스 파일은 여러가지 방법으로 공유 될 수 있다. 커널은 세 개의 관련 자료구조를 사용해서 오픈한 파일들을 표현한다.
- 식별자 테이블 : 각 프로세스는 자신만의 별도의 식별자 테이블을 가지고 있으며, 이들의 엔트리는 프로세스의 오픈된 파일 식별자로 인덱스된다. 각 오픈 식별자 엔트리는 파일 테이블 내의 한 개의 엔트리를 가진다.
- 파일 테이블 : 오픈 파일들은 모든 프로세스들이 공유하는 한 개의 파일 테이블로 표시된다. 각 파일 테이블 엔트리는 현재 파일 위치, 현재 가리키고 있는 식별자 엔트리들의 참조 횟수, v노드 테이블 엔트리로의 포인터로 구성된다.
- v-node 테이블 : 파일 테이블 처럼 v-노드 테이블은 모든 프로세스들이 공유한다.
10.9 I/O 재지정
- 리눅스 쉘은 표준 입력 및 출력을 디스크 파일과 연결할 수 있도록 해주는 I/O 재지정 연산자를 제공한다.
dup2(oldfd, newfd);
- dup2 함수는 식별자 테이블 엔트리의 이전 내용을 덮어써서 식별자 테이블 엔트리 old를 식별자 엔트리 newfd로 복사한다.
10.11 종합 : 어떤 I/O 함수를 이용해야 하는가
- G1 : 가능하면 I/O 함수를 사용하라
- G2 : 이진 파일을 읽을 때는 scanf나 rio_readlineb를 이용하지 말아라
- G3 : 네트워크 소켓에 대한 I/O를 위해서는 RIO 함수를 이용해라
백준
2164 카드2
#include <bits/stdc++.h>
using namespace std;
int main()
{
ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
queue<int> card_arr;
int card_num;
cin >> card_num;
for (int i = 1; i < card_num+1; ++i)
{
card_arr.push(i);
}
while (true)
{
if (1 == card_arr.size())
break;
card_arr.pop();
card_arr.push(card_arr.front());
card_arr.pop();
}
cout << card_arr.front();
return 0;
}
- QUEUE를 이용해서 푸는 문제
- QUEUE POP과 PUSH를 사용하면 쉽게 풀 수 있다.
KEYWORD
웹 서버란 무엇인가?
- 웹 서버는 웹 사이트를 구성하는 핵심 요소중 하나이다. 웹사이트를 방문할 때 사용자의 웹 브라우저는 웹서버에 요청을 보내고, 웹서버는 웹 페이지를 포함한 다양한 콘텐츠를 응답으로 전송하낟.
- 다음과 같은 역할 수행
- 웹 페이지 제공 : HTML, CSS, Javascript등 웹페이지를 구성하는 파일들을 저장하고 사용자의 요청에 따라 전송한다.
- 정적 콘텐츠 제공 : 웹 페이지에 포함된 이미지, 동영상, 음악 등 정적 콘텐츠를 저장하고 전송한다.
- 동적 콘텐츠 처리 : 서버 측 스크립팅 언어(PHP, Python, Ruby등)를 사용하여 동적으로 생성된 웹페이지를 제공한다.
- 보안 및 권한 관리 : 사용자의 접근 권한을 관리하고 웹사이트의 보안을 유지한다.
- HTTP 지원 : 웹 서버는 HTTP를 사용하여 웹 브라우저와 통신한다.
- 웹서버는 하드웨어와 소프트웨어 두 가지 측면에서 이해할 수 있다.
- 하드웨어 : 웹 서버 소프트웨어를 실행하는 컴퓨터를 의미한다. 웹사이트의 트래픽이 많을 경우 고성능의 컴퓨터가 필요하다
- 소프트웨어 : 웹서버 기능을 제공하는 프로그램이다. 대표적인 웹 서버 소프트웨어로는 APACHE, NGINX, IIS등이 있다.
- 웹서버의 종류
- APACHE : 가장 많이 사용되는 웹서버 소프트웨어, 무료이며 오픈소스고 다양한 플랫폼에서 사용할 수 있다.
- NGINX : 빠르고 효율적인 웹서버 소프트웨어 가볍고 높은 트랲픽을 처리하는데 적합하다
- IIS : MICROSOFT 에서 제공하는 웹 서버 소프트웨어. WINDOWS 운영체제에서 사용하기에 적합하다.
- 웹서버 선택시 고려사항
- 웹사이트의 트래픽
- 웹사이트의 기능
- 운영체제
- 사용 편의성
- 웹서버 관련 용어
- HTTP, HTTPS : 웹서버와 웹브라우저 간의 통신에 사용되는 프로토콜
- SSL/ TLS : HTTPS에 사용되는 보안기술
- CGI : 서버츨 스크립팅 언어를 사용하여 동적콘텐츠를 처리하는 기술
- 웹호스팅 : 웹 서버를 사용하여 웹사이트를 인터넷에 공개하는 서비스이다.
728x90
'Study > TIL(Today I Learned)' 카테고리의 다른 글
24.02.26 간단한 정리, 백준 (2) | 2024.02.27 |
---|---|
24.02.25 운영체제, 백준, KEYWORD (2) | 2024.02.25 |
24.02.23 CSAPP, 백준, KEYWORD (0) | 2024.02.24 |
24.02.22 백준,KEYWORD (1) | 2024.02.23 |
24.02.21 CSAPP, TCP/IP, 백준, C++ (1) | 2024.02.22 |