운영체제. 동기와 비동기의 차이(+ 블로킹과 논블로킹)

sanghee·2021년 12월 23일
0

👩‍💻면접 스터디

목록 보기
11/22

매주 진행하는 면접스터디에서 아래의 질문들에 대한 정리를 모은 글입니다.
Interview_Question_for_Beginner/OS
blocking, non-blocking and Async
동기 vs 비동기 (feat. blocking vs non-blocking)
https://www.youtube.com/watch?v=IdpkfygWIMk

비유를 통한 쉬운 설명

해야할 일(Task)이 빨래, 설거지, 청소가 있다고 가정하자. 이 일들을 동기적으로 처리한다면 빨래를 한 후 설거지를 하고 청소를 한다. 비동기적으로 일을 처리한다면 빨래 업체에 빨래를, 설거지 업체에 설거지를, 청소 업체에 청소를 시킨다. 셋 중 어느 것이 먼저 끝날지 알 수 없다. 일을 모두 마친 업체는 나에게 알려주기로 했으니 나는 다른 일을 한다.

📌Sync vc Async

일반적으로 메소드를 실행시킴과 동시에 반환 값이 기대되는 경우를 동기, 그렇지 않은 경우를 비동기라고 표현한다. 여기서 동시에라는 말은, 값이 반환되기 전까지 blocking되어 있다는 것을 의미한다. 비동기의 경우, blocking 되지 않고 이벤트 큐에 넣거나 백그라운드 스레드에게 해당 task를 위임하고 바로 다음 코드를 실행한다.

📌Blocking I/O Model

일단 I/O 작업을 User Level(Application)에서 직접 수행할 수 없다. 실제 I/O 작업은 Kernel Level(OS)에서 일어나는 과정이다.

  • User Level에 있던 Application이 I/O 작업을 처리하기 위해 커널(OS)에게 시스템 함수를 호출한다(System Call).
  • 이때 문맥교환(Context Switching)이 발생한다.
  • 커널이 해당 I/O 작업이 끝나고 데이터를 반환한다.
  • 그때가 되서야 애플리케이션 단의 스레드에 걸렸던 block이 풀린다.

애플리케이션 관점에서 보면 아무런 동작도 안하는 것처럼 보이지만 실제로는 커널에서 I/O 작업을 수행하느라 block이 되어 있는 것이다. 바로 이 부분이 blocking I/O의 문제점이며 개선 포인트이다.

📌Event Driven Model

이벤트 통지 모델이라고 부르며 Non-Blocking에서 제기된 문제를 해결하기 위해 고안되었다. Non-Blocking에서 애플리케이션에서 데이터가 준비되었는지 계속해서 확인하는 것이 아니라, Kernel Level에서 데이터가 준비되면 콜백 또는 이벤트를 발생시켜서 애플리케이션에 알린다. User Level에서 계속해서 데이터가 준비되었는지 확인할 필요 없이, 다음 작업을 수행하다가 커널에서 이벤트가 발생하면 그 작업에 해당하는 일을 처리하면 되는 것이다.

Synchronous(동기)

작업을 요청한 후 해당 작업의 결과가 나올 때까지 기다린 후 처리한다. I/O 작업 준비에 대한 이벤트를 기다렸다가 해당 이벤트가 발생하면 그에 따른 적합한 처리를 수행한다.

Asynchronous(비동기)

작업을 요청해놓고 다음 일을 하다가, 해당 작업이 완료되면 완료되었음을 통지받고 그에 따른 작업을 수행한다. I/O 작업이 completion되면 그에 적합한 Handler를 이용해 처리한다.

Blocking

I/O가 끝나 함수가 데이터를 반환(return)할 때까지 대기한다. 커널이 작업을 완료하기 전까지 유저 프로세스는 작업을 중단한 채 대기 큐에서 대기한다. I/O 작업은 CPU를 거의 쓰지 않기에 Blocking 방법은 CPU 자원 낭비가 심한다.

Non-Blocking

Blocking은 커널이 작업을 완료할 때까지 대기하므로 자원 낭비가 심하다. 이를 극복하고자 Non-Blocking이 만들어졌다. I/O 작업을 진행하는 동안 유저 프로세스의 작업을 중단시키지 않는다.

  • 유저 프로세스가 I/O 작업을 처리하기 위해 커널에 함수를 호출한다(System Call).
  • 커널에서 함수의 진행 상황과 상관없이 바로 결과를 반환한다(처음에는 완료하지 않았다는 결과 반환).

서버는 클라이언트가 요청한 사이즈에 맞는 데이터를 반환하기 위해 데이터를 축적한 후 반환한다. 여기서 문제는, 서버에서 요청한 사이즈에 맞는지 계속해서 확인해야 한다는 점이다(polling). 반환되는 데이터가 준비되었는지 확인하는 과정에서 수많은 클라이언트 요청이 동시 다발적으로 일어날 경우, CPU에 적지 않은 부담이 될 수 있다.

📌Sync, Async vs Block, Non-Block

  • Sync, Async: 결과값을 기다리는지?에 관한 개념이다.
  • Block, Non-Block: 제어권에 관한 개념이다.

📌예시: Sync + Non-Block

유저 Application이 커널에 시스템콜을 한다. 커널은 바로 결과가 완료되지 않았음을 통지한다. 이후 할 일을 하고 다시 물어보고, 결과값이 있다면 완료된 결과값을 준다.

시스템 콜을 하고, 결과값을 기다리고 받은 이후 다른 할 일을 했으므로 Sync이다.

아직 커널에서의 함수가 끝나지 않았으므로(제어권이 다른 함수로 넘어가지 않았으므로) Non-Block이다.

사실 전체적으로 본다면, 할 일을 한 이후에 완료된 결과값을 사용하므로 비동기라고도 볼 수 있다.

📌Blocking vc Non-Blocking

프로세스가 Running → Ready로 가면 작업이 중단된다.

  • Blocking: 애플리케이션 실행 시 대기큐(Ready Queue)에 들어가면서 요청에 대한 시스템 콜이 완료된 후에 응답을 보낸다.
  • Non-Blocking: 애플리케이션 실행 시 대기큐(Ready Queue)에 들어가지 않고 실행 여부와 관계없이 바로 응답을 보낸다.

Synchronous vs Asynchronous

  • Synchronous: 작업을 보내고 완료되었다는 System call을 기다린다.
  • Asynchronous: 작업을 보내고 다음 작업을 수행한다.

예시

  • 동기: 전화로 물어봐서 즉답을 얻는다.
  • 비동기: 이메일로 물어보고 메일 송신을 완료(return)했지만 답은 언제 올지 모른다.
  • 동기 + 블록킹: 전화를 했는데 상대방이 너무 바빠 전화를 받지 않음전화를 받을때까지 계속 대기
  • 동기 + 논블록킹: 전화를 했는데 안 받음끊었다가 나중에 다시 전화함계속 반복했다가 어느 순간에 받아서 답을 얻음
profile
👩‍💻

0개의 댓글