Sync, Async vs Blocking, non-Blocking

tess·2021년 8월 19일
0

내용에 들어가기에 앞서 이 내용은 추상적인 개념을 다루고 있기에, 추상적인 설명과 예시가 주된 내용임을 미리 알립니다.


오늘은 태선이 한 달 전부터 준비한 프러포즈를 하는 날이다.
반지는 이미 준비하여 주머니에 넣어 두었고, 깜짝 이벤트를 위해 친구들에게 한강 한적한 곳에 이벤트 장소를 꾸며달라고 말해두었다.
태선은 친구들이 한강에서 이벤트 장소를 준비하는 동안, 여자친구와 데이트를 할 것이다.

태선은 ENTJ답게 오늘의 데이트는 여자친구가 일이 끝나는 오후 5시부터 시작할 것이며,
친구들의 이벤트 준비는 오후 6시에 시작하여 8시 쯤 끝나는 것으로 철저히 계획했다.

태선은 5시에 여자친구를 만나 6시 쯤 이태원의 낭만 있는 오마카세에 들러 식사를 시작했다.
그리고 태선이 식사를 시작할 때 쯤, 태선은 친구들에게 이벤트 준비를 시작해달라고 여자친구 모르게 연락했다.

이벤트 준비가 제대로 되지 않으면 완벽을 추구하는 태선이 얼마나 면박을 줄 지 알기에, 친구들은 열심히 준비하기 시작했다.

식사 중 태선은 불안한 나머지 잠시 화장실에 들러 친구들에게 전화하여 다 되었는지 물어보았다. 친구들은 아직 진행중이라는 말을 하고 다시 이벤트를 준비했다.
태선은 아직 진행중이라는 대답을 듣고, 다시 자리로 돌아가 하던 식사를 마저 진행했다.

약 2분 후, 떨리는 마음을 참지 못한 태선은 여자친구가 보이지 않게 카톡으로 친구들에게 완료 되었냐고 물어보았다. 친구들은 태선의 마음을 이해하며 밥이나 먹으라고 말해주고, 아직 완료되지 않았다고 말해주었다.
태선은 다시 밥을 먹으며 여자친구와의 데이트를 즐겨야겠다고 마음먹었다.

약 20분 후 코로 들어가는지 입으로 들어가는지 모를 식사를 마치고, 계산을 하고 나오면서 모바일 영수증을 확인하는 척 친구들에게 얼마나 되었는지 물어보았다. 친구들의 대답은, 아직 다 안됐으니 제발 그만 좀 닦달하고 데이트나 잘하라는 말이었다.
태선은 여자친구와 다음 장소인 재즈바로 이동하면서 여자친구와 일상 대화를 나누었다.

재즈바에 도착한 시간은 약 7시 45분, 여자친구에게는 8시에 공연이 있으니 함께 보자고 말은 해두었지만, 사실 그 날은 라이브 재즈 공연이 없는 날이었다. 8시가 넘어도 친구들에게 연락이 오지 않자 태선은 한번 더 친구들에게 완료되었는지 카톡으로 물었고, 친구들은 드디어 이벤트 준비가 완료되었다고 말했다.

태선은 드디어 프러포즈를 할 수 있겠다는 마음에 여자친구의 손을 붙잡고 재즈바를 나와 차를 타고 이벤트 장소로 이동했다.

이벤트 장소에서의 모습은 여자친구를 경악시켰다.
개발자였던 태선은 바닥에 수놓은 촛불로 여자 친구의 마음을 도메인으로 한 api 요청을 보냈고, 그 아래에는 '내 평생의 refresh_token이 되어줘'라는 문구가 적혀 있었다.

여자친구는 무슨 말인지는 모르지만 일단 촛불이 있고 남자친구인 태선이 앞에서 무릎을 꿇고 반지를 건내니 프러포즈라는 것을 알았고, 뒤늦게 눈물을 흘리며 감동한 척했다.
태선은 이벤트가 성공했다며 친구들에게 감사 인사를 건냈고, 친구 중 한명은 중간에 너무 힘들어 event.preventDefault()메서드를 사용하려 했으나 태선의 이벤트 준비 요청은 DOM을 통한 이벤트라 내 마음에 버블링이 일어나 쓰지 못했다고 하며 태선의 프러포즈는 성공적으로 마무리 되었다.


소설을 쓰느라 이 글의 주제를 잊을 뻔 했지만, 위 내용은 내가 이해한 Block vs non-Block & Sync vs Async에 대해 작성해보았다.

먼저 non-Block 과 Async는 둘 다 '비동기'라는 것을 설명할 때 쓰이는 단어들이다.

그리고 나는 이 두 개념을 '결과값'을 기준으로 하는 Sync vs Async와 '제어권'을 기준으로 하는 Block vs non-Block으로 나누는 것으로 표현하겠다.
이렇게 말하면 두 개념의 차이가 잘 느껴지지 않는데,
위 소설에서 태선은 여자친구와의 데이트 중 친구들에게 진행 상황을 묻는다.
이 상황을 코드로 변환해보면,

//Sync-NonBlocking 태선
async 오늘 () {
  const 이벤트 = await 친구들의이벤트준비();
  function 데이트 () {
    const 데이트코스 = [식사, 재즈바, 카페]
    while (이벤트 === '아직 준비 중') {
      const 시간끌기 = 데이트코스.shift();
      시간끌기();
    }
    return;
  }
  데이트();
  한강으로출발();
  프러포즈(이벤트);
  뽀뽀();
}

대충 이런 느낌의 코드로 연출이 될 수 있다. 여기에서 동기적 처리와 비동기적 처리를 가르라고 한다면 비동기 처리에 대해 배워본 사람이라면 쉽게 가를 것이다.
하지만 여기에서 Sync-NonBlocking한 상황을 찾아보라고 한다면 어떤 것이 있을 것인가?

내가 의도한 방향의 대답은 데이트 함수이다.
위 소설에서 태선은 데이트 중 친구에게 연락하여 진행이 다 되었는지 지속적으로 묻는다. 그리고 친구는 연락에 회신으로 아직 완료가 되지 않았다고 말해준다.

이를 좀 더 주제에 친화적으로 접근하여 말을 바꿔보면,

태선은 친구들의 이벤트 준비가 완료되었는지 데이트 작업에 '제어권'을 가지고 실행하는 도중에 묻고, 친구들은 완료가 되지는 않았지만 아직 되지 않았다는 '결과값'을 내놓았다. 이는 Sync-NonBlocking한 상황이다.

만약 태선이 Sync-Blocking한 사람이라면, 친구들에게 이벤트를 준비해달라고 하고, 함께 이벤트를 준비하다가, 준비가 완료되면 그제서야 여자친구를 만나 한강으로 데리고 갈 것이다.

만약 태선이 Async-Blocking한 사람이라면, 친구들에게 오후 8시까지 이벤트를 준비해달라고 하고, 함께 이벤트를 준비하다가, 오후 8시가 딱 되면 준비가 완료되었든, 안되었든 여자친구를 데리고 한강으로 가서 이벤트를 할 것이다.

만약 태선이 Async-NonBlocking한 사람이라면, 친구들에게 오후 8시까지 이벤트를 준비해달라고 하고, 데이트를 하고 있다가, 오후 8시가 딱 되면 준비가 완료되었든, 안되었든 여자친구를 한강으로 가서 이벤트를 할 것이다.

이 쯤되면 슬슬 패턴이 보이지 않나,

sync한 태선은 이벤트가 모두 준비 완료되었을 때 여자친구와 한강을 간다.
async한 태선은 이벤트가 준비가 되든 안되든 정해진 시간이 되면 한강을 간다.

Blocking한 태선은 이벤트 준비를 함께 한다.
non-blocking한 태선은 이벤트를 준비하는 동안 여자친구와 데이트를 진행한다.

여기에서 데이트를 caller라고 정하고, 이벤트 준비를 callee라고 정했을 때 저 해당 표의 내용은 간단히 정리된다.

Sync-Blocking한 요청은 caller가 callee를 호출하면 제어권이 callee로 넘어가고 완료되면 결과값과 함께caller에 반환된다.

Async-Blocking한 요청은 caller가 callee를 호출하면 제어권이 callee로 넘어가고, 완료가 되든 안되든 callback이 불리면 callee의 현재 상태 결과값과 함께 caller에 반환된다.

Sync-NonBlocking한 요청은 caller가 callee를 호출하면 제어권은 callee로 갔다가 바로 다시 caller로 넘어오고, caller를 실행하며 중간 중간 완료를 확인한다.

Async-NonBlocking한 요청은 caller가 callee를 호출하면 제어권은 callee로 갔다가 바로 다시 caller로 넘어오고, callee에서 실행이 완료되면 callback을 통해 완료 여부에 관계없이 결과값이 반환된다.

해당 블로깅은 [10분 테코톡] 🎧 우의 Block vs Non-Block & Sync vs Async을 참고하여 작성했습니다.

profile
공부하여 이해가 된 것만 정리합니다.

0개의 댓글