반응형
✅ 동기/비동기
: 요청한 작업에 대해 완료 여부를 신경 써서 작업을 순차적으로 수행할지 여부에 대한 관점

📍동기 (Synchronous)
: 호출한 작업이 끝날 때까지 기다렸다가 다음 작업을 수행하는 방식
- 요청한 작업에 대한 순서가 보장됨
- 함수 A에서 함수 B를 호출하면, 리턴 값을 기다림
📍비동기 (Asynchronous)
: 호출한 작업의 완료 여부를 따지지 않고 자신의 다음 작업을 그대로 수행하는 방식
- 요청한 작업에 대한 순서가 지켜지지 않을 수 있음
- 함수 A에서 함수 B를 호출하면, 리턴 여부를 신경 쓰지 않고 동작
- 동시 처리를 통해 성능을 향상할 수 있음
✅ 블로킹/논블로킹
: 다음 작업을 처리하기 위해 현재 작업이 멈추는지(block) 여부에 대한 관점
📍블로킹 (Blocking)
: 요청한 작업이 끝날 때까지 기다리며 멈춰 있는 방식
- 호출자는 작업이 완료될 때까지 자신의 흐름을 멈춤
- 일반적으로 시스템 콜이나 네트워크 통신 등에서 흔히 사용됨
- 구현이 간단하고 직관적이지만, 비효율적일 수 있음
📍논블로킹 (NonBlocking)
: 요청한 작업의 결과가 준비되지 않았더라도 바로 반환되는 방식
- 호출자는 작업이 끝나지 않았더라도 자기 일을 계속 수행
- CPU 리소스를 낭비하지 않고 여러 작업을 병렬로 처리할 수 있음
- 단, 호출자가 반복적으로 작업 상태를 확인해야 하므로, 적절한 polling 주기를 설계해야 함
✅ 동기/비동기 + 블로킹/논블로킹 조합
- 동기/비동기는 `출력 순서`에 대한 개념
- 블로킹/논블로킹은 `병렬 실행`에 대한 개념

📍 동기 + 블로킹
: 다른 작업이 진행되는 동안 자신의 작업을 처리하지 않고(블로킹), 다른 작업의 완료 여부를 받아 순차적으로 처리(동기)
- 가장 기본적이고 직관적인 방식
- 커널이 작업을 완료할 때까지 프로세스는 대기 상태
- 많은 요청이 몰릴 경우 context switching 비용 증가
💡 대표적인 예시
- read(), write() 같은 system call
- Java의 기본 I/O (InputStream, OutputStream)
📍 동기 + 논블로킹
: 자신의 작업을 멈추지 않고(논블로킹), 작업 완료 여부를 반복적으로 확인하며 순차적으로 처리(동기)
- 작업이 즉시 반환되며, 완료 여부는 직접 확인 (polling)
- CPU 자원을 지속적으로 사용 → busy-wait 발생 가능
- 효율성은 떨어지지만 구현이 비교적 간단함
💡 대표적인 예시
- `recv()` with `O_NONBLOCK` 소켓 옵션
📍비동기 + 블로킹
: 작업 완료를 기다리지 않고 요청만 한 뒤(비동기), 특정 이벤트가 발생할 때까지 대기하는 방식(블로킹)
- 이벤트가 도착할 때까지 blocking system call 대기
- 일반적으로 잘 사용되지 않음
- 커널이 여러 I/O 요청을 관리 → 효율적인 처리 가능
- 처리 순서를 완전히 예측하기 어려움
💡 대표적인 예시
- `select()`, `poll()`, `epoll_wait()`
- Node.js 내부 이벤트 루프의 블로킹 wait
📍비동기 + 논블로킹
: 요청만 해두고 결과를 기다리지 않으며(비동기), 자신의 작업도 멈추지 않는 방식(논블로킹)
- 작업 요청 후 콜백, Future 등으로 결과를 나중에 수신
- 고성능 시스템에서 가장 선호되는 방식
- 구조가 복잡하고 디버깅 어려움
💡 대표적인 예시
- Java NIO의 `AsynchronousFileChannel`
- Node.js, Python `async/await`, JavaScript `fetch()`
✅ 요약
| 항목 | 동기(Synchronous) | 블로킹(Blocking) | 비동기(Asynchronous) | 논블로킹(Nonblocking) |
| 시스템 호출 완료를 기다림 | ⭕ | ⭕ | ||
| 즉시 반환 | ⭕ | ⭕ | ||
| 데이터와 함께 반환 | ⭕ | ⭕ | ⭕ | |
| 대기 큐에서 대기 | ⭕ |
참고: https://www.slideshare.net/slideshow/sync-asyncblockingnonblockingio/50573652
✨ 추가 질문
[ 논블로킹 I/O를 수행한다고 하면, 그 결과를 어떻게 수신할 수 있나요? ]
- Polling: 호출자는 반복적으로 I/O 대상에 접근하여, 데이터가 준비되었는지를 확인
- I/O Multiplexing: select(), poll(), epoll() 등의 시스템 콜을 사용해 여러 I/O 채널의 상태를 동시에 감시
- 이벤트 기반 처리: 이벤트 루프가 특정 이벤트를 감지하면 콜백 함수 호출
[ 동기이면서 논블로킹이고, 비동기이면서 블로킹인 경우는 의미가 있다고 할 수 있나요? ]
- 동기+논블로킹: 특정 작업의 결과가 필요한 경우에도 프로그램의 실행 흐름이 일시 중단되지 않고 다른 작업을 병렬로 처리할 수 있게 해 준다.
- 비동기 + 블로킹: 일반적으로 잘 사용되지 않는다.
[ I/O 멀티플렉싱에 대해 설명해 주세요. ]
하나의 프로세스 또는 스레드가 여러 I/O 객체(파일, 소켓 등)의 상태를 동시에 감시하는 기법이다.
I/O가 준비되었는지 감시하여 준비된 경우에만 실제 읽기/쓰기 작업을 수행한다.
ex) epoll()
- 감시를 위한 epoll 인스턴스 생성
- 관심 있는 fd를 epoll 인스턴스에 등록
- 등록한 fd들 중 이벤트가 발생할 때까지 대기
- 이벤트 발생 → 준비된 fd 리스트를 리턴
- 해당 fd에 대해 I/O 수행
반응형
'⚙️ CS > 운영체제' 카테고리의 다른 글
| [운영체제] 파일 시스템 (1) | 2025.05.07 |
|---|---|
| [운영체제] 페이지 교체 알고리즘 (0) | 2025.05.06 |
| [운영체제] 가상 메모리 & 페이징 & 세그멘테이션 (1) | 2025.05.06 |
| [운영체제] 메모리 할당 방식 (1) | 2025.04.30 |