CS&Concepts

[CS] Sync. and Async.

곽일땡 2022. 11. 22. 02:07

프로그래밍에서 얘기하는 Synchrony(동기) / Asynchrony(비동기)에 대해.

 

먼저, 강의에서 제공된 설명은 다음과 같다.


  • 블로킹 vs 논블로킹 (제어권이 누구한테 있는가)
    • 블로킹
      • 함수 A가 함수 B를 호출한 뒤, 함수 B의 리턴값이 올 때까지 기다린 후 진행되는 것
      • 즉, 제어권을 넘겨주는 것
    • 논블로킹
      • 함수 A가 함수 B를 호출한 뒤, 함수 B의 작업 완료 여부와 상관 없이 진행되는 것
      • 즉, 제어권을 넘겨주지 않는 것
  • 동기 vs 비동기 (호출되는 함수의 작업 완료 여부를 신경쓰는가)
    • 동기
      • 함수 A와 함수 B를 호출할 때, 함수 A가 함수 B의 리턴값을 계속 확인하면서 신경 쓰는것
    • 비동기
      • 함수 A와 함수 B를 호출할 때, 함수 A가 함수 B의 작업 완료 여부는 신경 쓰지 않는 것

개념을 처음 접하는 입장에서, 그렇게 크게 와닿는 설명은 아니라고 느꼈다. 무엇보다 동기/비동기 설명에서 쓰인 "신경쓴다"라는 동사의 의미가 구체적으로 무엇인지 잘 짐작이 되지 않았다. 또한, 두 개념(블로킹 여부와 동기/비동기)의 관점이 다르므로 별개의 개념이라 설명하였는데, 관점이 다른 것은 이해가 가겠으나 '실질적으로' 같은 의미처럼 느껴지기도 한다. 가령, "함수 A가 함수 B의 작업 완료 여부를 신경 쓰지 않는다"라면, 결국 함수 B의 작업 완료 여부와 관계없이 함수 A의 작업이 진행된다는 얘기 아닌가? (그렇지 않다면 B의 작업 완료 여부에 A의 작업이 간섭받게 되는 것이니). 그렇다면 '비동기'의 설명과 '논블로킹'의 설명은 같은 의미가 되어버린다.

 

그렇다면 꼬리를 물고 다음 의문이 떠오른다. "비동기 처리를 했는데, 블로킹일 수 있는가?" 혹은 "동기적으로 처리하면서 넌블로킹일 수 있는가?". 그게 가능하다면, 과연 그게 의미가 있는 프로그래밍인가? 등등... 구글링해본 결과 가능하다며 예시를 들어놓은 블로그 글들이 나오긴 하는데, 여기에 대한 답은 일단 뒤로 미루고 영문 검색결과를 읽으며 좀 더 정확한 정의에 대해 탐구해봤다.

 

먼저, Synchrony라고 하면 일상적으로는 뭔가가 시간적으로 동시에 이루어지는 것을 의미하는데, 어째서 프로그래밍에서는 Asynchrony가 뭔가를 병렬적으로 처리하는걸 의미하는지 알아보자.

 

https://en.wikipedia.org/wiki/Synchronization_(computer_science)#Thread_or_process_synchronization 

 

Synchronization (computer science) - Wikipedia

Concept in computer science, referring to processes, or data In computer science, synchronization refers to one of two distinct but related concepts: synchronization of processes, and synchronization of data. Process synchronization refers to the idea that

en.wikipedia.org

When a job arrives at a fork point, it is split into N sub-jobs which are then serviced by n tasks. After being serviced, each sub-job waits until all other sub-jobs are done processing. Then, they are joined again and leave the system. Thus, parallel programming requires synchronization as all the parallel processes wait for several other processes to occur.

Computer science에서의 synchronization이란, 어떤 한 작업이 여러개의 하위작업으로 분기되었을 때, 그 분기된 작업들이 완료되어 '동시에' System을 떠나는 것을 의미한다. 즉, 하위작업을 병렬적으로 동시에 진행하는게 아니라, 하위작업들이 분기된 뒤 다시 원래 작업으로 완전히 '합류'되는 시점을 '동기화'한다는 의미인 것이다.

Thread synchronization is defined as a mechanism which ensures that two or more concurrent processes or threads do not simultaneously execute some particular program segment known as critical section. Processes' access to critical section is controlled by using synchronization techniques. When one thread starts executing the critical section (serialized segment of the program) the other thread should wait until the first thread finishes. If proper synchronization techniques are not applied, it may cause a race condition where the values of variables may be unpredictable and vary depending on the timings of context switches of the processes or threads.

여기서 말하는 "concurrent"또한, 일상에서처럼 "시간적으로 동시에" 일어난다는 뜻이 아니라, 싱글 코어에서 여러개의 작업을 처리한다는 맥락으로 이해해야 한다. 여러개의 context, 즉 하위 작업으로 나눠지는 작업을 수행할 때, 각각의 스레드가 프로그램의 'critical section'에 접근할 때 일어날 수 있는 충돌을 방지하기 위해 동기화가 필요하다는 설명이다. 이렇게 하지 않으면 변수의 값이 'context switch'의 타이밍에 따라 바뀌는 등의 문제가 생길 수 있다.

 

Concurrency, context switch라는 용어의 의미가 잘 정리된 블로그 글을 하나 링크해두겠다.

https://seamless.tistory.com/42

 

동시성(Concurrency) vs 병렬성(Parallelism)

서점에 가면 다양한 언어별로 동시성을 다루는 책들을 많이 볼 수 있습니다. 프로그래밍을 하다 보면 이러한 동시성 처리가 필요한 경우가 있습니다. 그런데 동시성이라는 말을 종종 병렬성과

seamless.tistory.com

영문 위키피디아의 설명에 계속해서 "각각의 하위작업들은 다른 하위작업이 완료될 때까지 기다린다"는 말이 나오는 것으로 보아, synchronization을 위해서는 blocking 처리가 (거의) 필수인 것으로 보인다.

 

https://en.wikipedia.org/wiki/Asynchrony_(computer_programming) 

 

Asynchrony (computer programming) - Wikipedia

Computer programming technique Asynchrony, in computer programming, refers to the occurrence of events independent of the main program flow and ways to deal with such events. These may be "outside" events such as the arrival of signals, or actions instigat

en.wikipedia.org

Asynchrony, in computer programming, refers to the occurrence of events independent of the main program flow and ways to deal with such events. These may be "outside" events such as the arrival of signals, or actions instigated by a program that take place concurrently with program execution, without the program blocking to wait for results.

그럼 이제 Asynchrony는 반대로 이해하면 될 것 같다. 즉 프로그래밍에서의 '비동기'란, 하나의 프로그램 안에서 작업 분기가 발생했을 때, 하위작업의 결과를 기다리기 위해 'main program flow'의 진행을 멈추지 않고 처리하는 것을 말한다. 그리고 각각의 하위작업들은 각자의 작업이 완료되는 시점에 결과를 반환하고 종료되므로, 비동기 처리에서는 말그대로 분기된 작업이 "merge"되는 시점이 통일되지 않는다. 그래서 'Asynchrony'라 말하는 것이다.

 

Sync.와 Async.의 개념을 그림으로 도식화 하면 다음과 같을 것이다.

 

Sync : 모든 subtask가 한번에 분기하고 한번에 합류. (점선 부분에서는 작업하지 않음) / Async : 각 subtask가 각자의 완료시점에 합류.

 

여기까지 살펴본 결과, 영문 위키피디아의 설명들은 일관적으로 Sync.는 blocking과, Async는 non-blocking과 함께 설명하고 있다. 용어의 의미에 있어서, block / non-block은 하위작업 실행시 main 작업을 중지시킬지 말지에 대해서만 국한된 좁은 의미의 용어이고, sync / async는 분기 작업이 필요할 때의 프로그래밍 방법론을 이르는 넓은 의미의 용어로 생각되지만, sync 처리를 non-block 방식으로 하면 각각의 하위작업이 'critical section'에 접근하면서 생기는 충돌이 예방되지 않을 것이고, async 처리를 block 방식으로 하면 (하나의 작업이 이루어지는동안 다른 작업이 정지하도록 하면) 굳이 하위작업들의 종료시점이 일치하지 않아도 되도록 처리할 이유가 없을 것이다. 영문 위키까지 읽어본 시점에서는 Sync와 blocking, Async와 non-blocking은 필수불가결의 개념처럼 보인다.

 

그런데...

 

https://www.youtube.com/watch?v=HKlUvCv9hvA 

 

해당 영상에서는 완벽히 Sync 여부와 block 여부를 분리해서 설명하고 있다. 영상에 따르면,
7:00

병렬작업이 진행되더라도 두 작업의 시작, 종료 시점을 일치시킨다면 Sync이다.
또는 한 작업의 종료 시점과 다음 작업의 시작 시점을 일치시키는 것도 Sync이다.

또, 메소드의 return 시점과 결과를 전달받는 시점이 일치된다면 Sync이다.
(반대는 모두 Async)

8:40
외부와의 I/O 상황이나, 멀티쓰레드 작업 등을 할 때, 말그대로 작업을 수행하는 서로 다른 주체가 서로의
작업을 block하는지 여부에 따라 block/non-block을 구분한다.

즉 영상의 설명대로라면, 영문 위키의 설명은 Sync/Async에 대해서 각각 한정적인 경우만을 설명한 것이 된다. 또 같은 코드를 두고도 그 대상에 따라 Sync인지 Async인지가 달라지기도 한다.

 

(뭔가 영문위키 괜히 들쑤시면서 삽질한 기분이지만.. 여기까지 정리하고 넘어가자.)