
제어권
함수의 코드나 프로세스의 실행 흐름을 제어할 수 있는 권리를 말한다.

호출한 작업이 진행되는 동안 자신의 작업을 멈추고 호출한 작업이 끝난 후 그 결과를 받으며(Blocking), 호출한 작업의 완료 여부를 받은 후 순차적으로 자신의 작업을 처리(Sync)하는 방식이다.
실생활 예시
- 사장🥸: (알바생a에게 커피a를 부탁한다.)
- 알바생a: 네. (커피a 제작 중)
- 사장🥸: (알바생a이 작업을 다 할 때 까지 아무 일도 하지 않고 기다린다.) -> 블로킹
- 알바생a: (커피a을 제작 완료) 커피1 제작 완료 했습니다.
- 사장🥸: (알바생b에게 커피b를 부탁한다.) -> 동기 (순차적이다.)
- 알바생b: 네. (커피b 제작 중)
- 사장🥸: (알바생b가 작업을 다 할 때 까지 아무 일도 하지 않고 기다린다.) -> 블로킹
- 알바생b: (커피b를 제작 완료) 커피b 제작 완료 했습니다.
- 사장🥸: (알바생c에게 커피c을 부탁한다.) -> 동기 (순차적이다.)
...
코드 동작 예시
const fs = require('fs'); // 파일 시스템 모듈 불러오기
// 동기적으로 파일 읽기
const data1 = fs.readFileSync('file1.txt', 'utf8'); // file1을 sync으로 read 함
console.log(data1); // 파일 내용 출력하고 적절한 처리를 진행
const data2 = fs.readFileSync('file2.txt', 'utf8');
console.log(data2);
const data3 = fs.readFileSync('file3.txt', 'utf8');
console.log(data3);
호출한 작업이 진행되는 동안에도 자신의 작업을 처리하고 호출한 작업의 결과 처리 유무를 바로 받으며(Non-Blocking), 호출한 작업의 완료 여부를 받은 후 순차적으로 자신의 작업을 처리(Sync)하는 방식이다.
실생활 예시
- 사장🥸: (알바생a에게 커피a를 부탁한다.)
- 알바생a: 네. (커피a 제작 중)
- 사장🥸: 커피a 다 만들었나요? -> 동기, 논블로킹 (알바생a를 끊임없이 확인하며, 알바생a의 작업 결과를 기다린다.)
- 알바생a: (커피a 제작 중) 만드는 중 입니다. -> 논블로킹 (처리 유무를 바로 리턴한다.)
- 사장🥸: 커피a 다 만들었나요?
- 알바생a: (커피a 제작 중) 만드는 중 입니다.
- 알바생a: (커피a 제작 완료) 커피a 제작 완료 했습니다.
- 사장🥸: (알바생b에게 커피b를 부탁한다.) -> 동기 (다른 일을 하지 않고, 알바생a의 작업이 끝난 후 자신의 일을 처리한다. 즉, 순차적이다.)
- 알바생b: 네. (커피b 제작 중)
- 사장🥸: 커피b 다 만들었나요?
- 알바생b: (커피b 제작 중) 만드는 중 입니다.
- 사장🥸: 커피b 다 만들었나요?
...
코드 동작 예시
동기 + 논블로킹 코드를 표현하는데 적합한 대중적인 언어로 자바를 들 수 있다. 스레드 객체를 만들어 요청 작업을 백그라운드에 돌게 하고, 메인 메서드에서 while문을 통해 스레드가 모두 처리되었는지 끊임없이 확인하고, 처리가 완료되면 다음 메인 작업을 수행한다.
// Runnable 인터페이스를 구현하는 클래스 정의
class MyTask implements Runnable {
@Override
public void run() {
// 비동기로 실행할 작업
System.out.println("Hello from a thread!");
}
}
public class Main {
public static void main(String[] args) {
// Thread 객체 생성
Thread thread = new Thread(new MyTask());
// 스레드 실행
thread.start();
// Non-Blocking이므로 다른 작업 계속 가능
System.out.println("Main thread is running...");
// Sync를 위해 스레드의 작업 완료 여부 확인
while (thread.isAlive()) {
System.out.println("Waiting for the thread to finish...");
}
System.out.println("Thread finished!");
System.out.println("Run the next tasks");
}
}
호출한 작업이 진행되는 동안 자신의 작업을 멈추고 호출한 작업이 끝난 후 그 결과를 받으며(Blocking), 순차적으로 작업이 수행됨을 보장하지 않는(Async) 방식이다. 실무에서 잘 마주하지 않아 다룰 일이 거의 없다.
Sync-blocking과 개념적으로 차이가 있지만, 성능적으로 차이가 없다. 보통 Asnyc-blocking은 개발자가 Async-NonBlocking으로 처리하려다가 실수하는 경우에 발생한다. 그래서 이 방식을 안티 패턴이라고 치부하기도 한다.
- 사장🥸: (알바생a에게 커피a를 부탁한다.)
- 알바생a: 네. (커피a 제작 중)
- 사장🥸: (알바생b에게 커피b를 부탁한다.) -> 비동기
- 사장🥸: (알바생b가 작업을 다 할 때 까지 기다린다.) -> 블로킹
- 알바생b: (커피b 제작 완료) 커피b 제작 완료 했습니다.
- 사장🥸: (알바생c에게 커피c를 부탁한다.) -> 비동기
- 알바생a: (커피a 제작 완료) 커피a 제작 완료 했습니다. -> 비동기 (순차적으로 작업이 수행됨을 보장하지 않는다.)
- 알바생c: 네. (커피c 제작 중)
- 사장🥸: (다른 작업을 한다.) -> 비동기
...
호출한 작업이 진행되는 동안에도 자신의 작업을 처리하고 호출한 작업의 결과 처리 유무를 바로 받으며(Non-Blocking), 순차적으로 작업이 수행됨을 보장하지 않는(Async) 방식이다.
실생활 동작 예시
- 사장🥸: (알바생a에게 커피a를 부탁한다.)
- 알바생a: (커피a 제작 중) 만드는 중 입니다. -> 논블로킹 (처리 유무를 바로 리턴한다.)
- 사장🥸: (알바생b에게 커피b를 부탁한다.) -> 비동기
- 알바생b: (커피b 제작 중) 만드는 중 입니다. -> 논블로킹 (처리 유무를 바로 리턴한다.)
- 사장🥸: (알바생c에게 커피c를 부탁한다.)
- 알바생c: (커피c 제작 중) 만드는 중 입니다. -> 논블로킹 (처리 유무를 바로 리턴한다.)
- 사장🥸: (다른 작업을 한다.)
- 알바생b: (커피b 제작 완료) 커피b 제작 완료 했습니다. -> 비동기 (요청 순서와 처리 순서가 다르다.)
- 알바생a: (커피a 제작 완료) 커피a 제작 완료 했습니다.
- 알바생c: (커피c 제작 완료) 커피c 제작 완료 했습니다.
...
코드 동작 예시
Sync Blocking에서 구현한 코드를 Asnyc Non-Blocking 방식으로 구현한 것이다. 차이점은 호출 함수에 콜백 함수를 넣음으로써 작업의 결과를 후처리 할 수 있다.
// 비동기적으로 파일 읽기
const fs = require('fs'); // 파일 시스템 모듈 불러오기
fs.readFile('file.txt', 'utf8', (err, data) => { // 파일 읽기 요청과 콜백 함수 전달
if (err) throw err; // 에러 처리
console.log(data); // 파일 내용 출력
});
fs.readFile('file2.txt', 'utf8', (err, data) => {
if (err) throw err;
console.log(data);
});
fs.readFile('file3.txt', 'utf8', (err, data) => {
if (err) throw err;
console.log(data);
});
console.log('done'); // 작업 완료 메시지 출력
https://inpa.tistory.com/entry/%F0%9F%91%A9%E2%80%8D%F0%9F%92%BB-%EB%8F%99%EA%B8%B0%EB%B9%84%EB%8F%99%EA%B8%B0-%EB%B8%94%EB%A1%9C%ED%82%B9%EB%85%BC%EB%B8%94%EB%A1%9C%ED%82%B9-%EA%B0%9C%EB%85%90-%EC%A0%95%EB%A6%AC
https://hamait.tistory.com/m/930