2022. 12. 10. 16:02ㆍ카테고리 없음
IO: input /output의 약자이다. 데이터 입출력
I/O 종류:
network :(socket) 통해서 데이터가 입출력된다.
*backend server: 네트워크 상의 요청자들과 각각 소켓을 열고 통신한다.
file:파일 통해서 프로세스가 서로 공유하며 통신 한다.
pipe: os에서 제공하는 pipe 통해서 프로세스간의 통신시
device( 모니터 , 키보드 ): 입출력
blok I/O :i/o 작업을 요청한 프로세스/스레드는 요청이 완료 될때 까지 블락( 기다린다) 된다.
read 시스템콜을 호출하는 데 , 해당 시스템콜을 호출한 thread는 블락이 되고 컨텍스트 스위칭이 되면서 kernel모드가 실행이 되고 , 커널에서는 read I/O를 요청하면 관련 디바이스가 시간이 흐른뒤 읽을 준비가 되었다고 응답을 주면 커널이 그 응답을 받고 그 응답을 바탕으로 준비가 된 DATA를 커널 모드에서 USER모드로 옮기게 된다. 그때 블락이 된 THREAD는 꺠어나서 이어서 진행이 된다.
1)read 시스템콜은 recv_buffer에 데이터가 들어 올때까지 기다려야 한다.
2)또한 write 시스템콜은 send_buffer가 가득 찰수있는데 그때 더이상 데이터를 넣을수 없다보니 send_buffer가 비워질때까지 write시스템 콜은 기다려야 한다.
non-block I/O: 프로세스/스레드를 블락시키지 않고 요청에 대한 현재 상태를 즉시 리턴
read 시스템 콜을 호출을 시켰다 그러면 커널모드가 실행이 되고 커널에서 read I/o 관련 디바이스에게 요청을 보내고
그다음에 커널에서 바로 리턴을 시킨다, 아직 요청한 데이터가 준비 되지 않았기 때문에 리눅스 기준으로 -1값을
리턴하고 에러코드와 함께 리턴을 한다, 이때 쓰레드는 block I/O와 다르게 non-block I/O 기에 기다리지않고
이어서 다른 코드 실행된다, 그런중 I/O 디바이스로 부터 읽을 준비가 되었다는 응답이 오게 되고 커널은 데이터를 읽을 준비가 된다 , 그동안 쓰레드는 다른 코드를 진행하다가 다시 read 시스템 콜을 호출한다, 마찬가지로 non-block I/O 로 시스템 콜 보낸다 .그러면 커널로 컨텍스트 스위칭이 되고 이때 커널이 데이터를 전송하게 되고 USER 모드로 가서 데이터를 다 읽고 작업 처리 한다.
소켓 A 는 S로 부터 데이터가 들어오지 않을시 recv_buffer에 데이터가 없다고 알려주고 read 시스템 콜 호출후 종료
소켓 S는 send_buffer 공간이 없다고 해도 write시스템콜을 블락(기다리지)않고 적절한 에러코드와 함께 write를 반환한다.
non-block I/o 이슈
I/o 작업 완료를 어떻게 확인 할 것 인가?
non - block I/O 결과 처리 방식
1.완료되었는지 반복적으로 확인한다.
결과: 완료된 시간과 완료를 확인한 시간 사이의 갭으로 인해서 처리 속도가 느려질 수 있다. 또한 완료됐는지 반복적으로 확인하는 것은 CPU낭비가 발생 한다.
소켓 연결시에도 데이터가 왔는지 안왔는지 많은 클라이언트들로 부터 검사하고 한다는 게 너무 비효율 적이다 ,
그렇다고 블로킹 모드로 한다면 A라는 소켓으로 부터 데이터가 오는 것을 블로킹해서 기다리게 된다, 그러면
A가 데이터를 보낼때까지 다른 친구들이 서버에서 요청을 보내도 계속 기다리고 있게 된다 .
= 데이터다 들어온것을 커널에서 확인해서 그것들 우선처리하는 것
2. I/o multiplexing
: 관심있는 I/O 작업들을 동시에 모니터링 하고 그중에 완료된 I/O 작업들을 한번에 알려준다.
<I/O Multiplexing종류>
select
poll
epoll :리눅스
kqueue:맥,os
IOCP(I/O completion port):윈도우
핵심 :
non- block I/O를 통해 I/O 를 통해 I/O 요청완료 전에도 다른 일을 할 수 있다는 것 !
( I/O 작업 하는 동안에 CPU가 다른 작업을 할 수 있다.)