[운영체제] 동기와 비동기, 블로킹과 논블로킹

지니🧸·2023년 4월 7일
0

CS 저장소

목록 보기
23/48

🎷 동기 vs. 비동기

호출되는 함수의 작업 완료 여부를 신경쓰는지의 여부

동기: 함수 A가 함수 B를 호출한 뒤, 함수 B의 리턴값을 계속 확인하면서 신경 씀

비동기: 함수 A가 함수 B를 호출할 때 콜백 함수를 함께 전달해서, 함수 B의 작업이 완료되면 함께 보낸 콜백 함수를 실행함

  • 함수 A는 함수 B를 호출한 후로 함수 B의 작업 완료 여부는 신경쓰지 않음

🎷 블로킹 vs. 논블로킹

제어권: 자신의 코드를 실행할 권리

함수 A가 함수 B를 호출했을 때 제어권을 어떻게 처리하느냐의 문제

블로킹: 함수 A가 함수 B를 호출하면 A가 B에게 제어권을 넘겨줌

  1. 함수 A가 함수 B를 호출하면서 B에게 제어권을 넘김
  2. 제어권을 넘겨받은 B는 함수를 실행. A는 B에게 제어권을 넘겨줬기 때문에 함수 실행 정지
  3. B는 실행이 끝나면 자신을 호출한 A에게 제어권을 돌려줌

논블로킹: 함수 A가 함수 B를 호출해도 제어권은 A가 갖고 있음

  1. 함수 A가 함수 B를 호출하면 함수 B가 실행되는 동안에도 함수 A가 제어권을 갖고 있음
  2. 함수 A가 제어권을 계속 갖고 있어서 함수 B가 실행되는 동안에도 자신의 코드를 계속 실행함

🎷 동기-블로킹, Sync-Blocking

함수 A는 함수 B의 리턴값을 필요로 함 (동기)
그래서 제어권을 함수 B에게 넘겨주고, 함수 B가 실행 완료하여 리턴값과 제어권을 돌려줄 때까지 기다림 (블로킹)

🎷 동기-논블로킹, Sync-Nonblocking

함수 A는 함수 B를 호출할 때 제어권을 주지 않고 자신의 코드를 계속 실행함 (논블로킹)
그런데 함수 B의 리턴값이 필요하기 때문에 중간중간 함수 B에게 함수 실행을 완료했는지 물어봄 (동기)

🎷 비동기-논블로킹, Async-Nonblocking

함수 A가 함수 B를 호출할 때 제어권을 주지 않고 자신의 코드를 계속 실행함 (논블로킹)
함수 B를 호출할 때 콜백 함수를 함께 줘서 함수 B는 자신의 작업이 끝나면 콜백함수를 실행함 (비동기)

🎷 비동기-블로킹, Async-blocking

함수 A는 함수 B의 리턴값에 신경쓰지 않고 콜백함수를 보냄 (비동기)
함수 A는 함수 B의 작업에 관심이 없지만 제어권을 넘기기 때문에 (블로킹) 자신과 관련없는 함수 B의 작업이 끝날 때까지 기다려야 함

🎷 동기-블로킹과 비동기-블로킹의 의미

동기-논블로킹
(예) 게임에서 데이터 로드율 표시: 맵을 이용할 때 맵 데이터를 계속 물어보지만 제어권은 나에게 있어 화면에 로드율이 표시됨

  • 논블로킹으로 자신의 작업을 계속하고 있지만 다른 작업과의 동기를 위해 계속서 다른 작업이 끝났는지 조회
  • 자주 사용되지는 않음

비동기-블로킹에서 함수 A는 함수 B와 관련이 없음에도 제어권을 넘겨서 B의 작업을 기다려야 하기 때문에 의미 없음

🎷 I/O 멀티플렉싱

멀티플렉싱: 효율성을 높히기 위해 물리적 장치를 최소한으로 사용하여 최대한의 데이터를 전송하는 기술

Sync-Blocking I/O, 동기-블로킹 I/O

일반적으로 흔하게 생각하는 I/O 모델

  • 프로세스는 커널에게 I/O를 요청하는 함수를 호출(시스템 콜)한 뒤 커널이 작업 결과를 반환하기까지 중단된채 대기함(block)
  • 프로세스는 이 동안 CPU를 점유하지 않고 커널의 응답만 기다리는 상태가 됨
  • 커널의 응답이 되돌아옴과 동시에 반환된 데이터가 유저 공간으로 (sync) 오면 유저는 unblocking되어 반환받은 데이터 처리

특징

  • 시스템 콜마다 스레드를 생성하므로 I/O 요청이 적은 서비스에 적합
  • 요청 수가 많아지면 한 작업당 한번의 컨텍스트 스위치 발생 > 성능 저하

Sync-Non-blocking I/O, 동기-논블로킹 I/O

소켓 생성시 O_NONBLOCK 옵션으로 구성

  • 해당 소켓으로 I/O 시스템 콜하면 즉시 결과 반환 받음

  • 아직 읽을 데이터가 없다면 바로 -1 반환. 실패 유형은 오류코드(errno)로 구분됨

  • 수행 결과와 errno를 즉시 받아보고 더 물어볼지 말지를 결정하기 때문에 I/O 작업이 완료되지 않아도 프로세스는 block 상태 되지 않음

  • 제어권을 반환받고 나면 다른 작업도 처리할 수 있을거 같아 Blocking보다 개선된 모델이라 생각할 수 있지만, 프로세스는 원하는 결과를 반환받을 때까지 계속 상태를 체크해야 한느 busy-wait 상태로 빠짐

    • 특별한 수확 없이 컨텍스트 스위치만 빈번해짐
  • loop 내 적정한 polling 주기 필요

    • 주기가 너무 길면 데이터는 준비 되었음에도 후속 처리가 늦어짐
    • 주기가 너무 짧으면 커널 입장에서는 의미 없는 리턴을 자주해야 돼서 작업의 지연 초래

I/O Multiplexing
모든 sync 모델은 요청한 순서대로 작업을 완료시키기 때문에 2개 이상의 파일을 동시에 처리하기 위해서는 성능을 위해서 멀티프로세스/멀티스레드로 동작해야 함

  • 멀티프로세스 환경에서는 동기화 문제를 고려해야 해서 더 복잡해짐

Async-Blocking I/O, 비동기-블로킹 I/O

한 프로세스가 여러 파일을 관리하는 기법
프로세스에서 특정 파일에 접근할 때 파일 디스크립터를 사용하는데, FD를 어떻게 감시하냐가 맹점
어떤 상태로 대기하는지에 따라 select, poll 등 다양한 기법

select

  • FD를 배열에 저장해두고 각 FD의 상태를 감시할 수 있음
  • 3가지 유형으로 소켓을 목록화하여 감시할 수 있음
      1. 수신한 데이터를 지니고 있는 소켓이 존재하는가?
      1. 블로킹되지 않고 데이터의 전송이 가능한 소켓은 어느 것인가?
      1. 예외상황이 발생한 소켓은 어느 것인가?

동작 과정
1. FD 설정, 검사의 범위 지정, 타임아웃 설정
2. select 함수 호출
3. 호출결과 확인

select 함수
파라미터

  • maxfd: 검사 대상이 되는 FD의 수
  • readset: 수신된 데이터의 존재여부에 관심있는 fd 정보를 fd_set형 변수에 등록해서 그 변수의 주소값
  • writeset: 블로킹 없는 데이터 전송의 가능여부에 관심있는 fd 정보를 fd_set형 변수에 등록해서 그 변수의 주소값
  • exceptset: 예외상황의 발생여부에 관심있는 fd 정보를 fd_set형 변수에 등록해서, 그 변수의 주소값
  • timeout: select 함수 호출 이후에 무한정 블로킹 상태에 빠지지 않도록 time-out 설정하기 위한 인자

return 값:

  • 오류 발생: -1
  • time-out으로 인한 반환: 0
  • 관심대상으로 등록된 fd에 변화 발생: 0보다 큰 값

참고:

profile
우당탕탕

0개의 댓글