본문 바로가기
TIL (Today I Learned)

[CS] 동기(Sync), 비동기(Async)

by Bokoo14 2024. 2. 16.

[참고]

더보기

https://inpa.tistory.com/entry/WEB-%F0%9F%8C%90-%EB%B9%84%EB%8F%99%EA%B8%B0Async%ED%86%B5%EC%8B%A0-%EB%8F%99%EA%B8%B0Sync%ED%86%B5%EC%8B%A0

 

🌐 웹의 비동기(Async) / 동기(Sync) 통신 정리

웹에서의 비동기와 동기 웹 개발을 하다보면 비동기(Async)와 동기(Sync)라는 용어를 자주 접하게 될 것이다. 이 두 용어는 웹에서 데이터를 주고받는 방식을 설명하는데 사용되는데, 동기(Sync)는

inpa.tistory.com

https://velog.io/@s_sub/Swift-%EB%B9%84%EB%8F%99%EA%B8%B0-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D

 

[Swift] 비동기 프로그래밍

동기 vs 비동기 / 직렬 vs 동시 / 동시성 프로그래밍 / DispatchQueue / GCD 종류 /.main /.global() /label: / GCD 주의사항 /반드시 메인큐 /컴플리션핸들러 /강한 참조 / Async&Await / 동시성 프로그래밍 문제점

velog.io

https://green1229.tistory.com/44

 

Concurrent Programming

안녕하세요. 그린입니다! 이번 포스팅에서는 Concurrent Programming(동시성 프로그래밍)이 무엇인지 그리고 어떻게 사용하는지에 대해 알아보려합니다. 우선, 동시성 프로그래밍을 알기전 전반적으

green1229.tistory.com

https://ios-development.tistory.com/958

 

[iOS - swift] Async, Await 사용 방법

Async, Await 이란? 기존에 비동기 처리 방식은 DispatchQueue나 completionHandler를 사용하여 처리했지만, 더욱 편하게 비동기 처리할 수 있는 문법 // DispatchQueue 사용한 비동기 처리 DispatchQueue.global.async { }

ios-development.tistory.com

https://jeong9216.tistory.com/498

 

[Swift] async / await 간단 정리 & 실습

서론 async / await에 대한 Swift 가이드를 읽으면서 한숨이 푹 나왔습니다. 이게 무슨 말인지 모르겠고... 단어도 어렵고 ㅎㅎ;; async / await에 대해 따로 정리해야할 필요성을 느껴 포스팅을 하게 되었

jeong9216.tistory.com

 

https://sujinnaljin.medium.com/swift-async-await-concurrency-bd7bcf34e26f

 

[Swift] async / await & concurrency

Swift 5.5 에서 등장한 비동기와 동시성을 위한 방법을 알아봅시다

sujinnaljin.medium.com

 

 

 

 

📝 동기(Sync)?

작업에 대한 요청과 결과를 동시에 실행하며 해당 들어온 작업이 처리될 때까지는 다른 작업의 요청을 받을 수 없다.

  • 다른 쓰레드로 보낸 작업이 끝날 때까지 기다린다.
  • 다른 작업을 처리할 수 없다.
  • 요청과 응답이 동시에 일어난다
  • 웹페이지를 새로고침하면서 데이터를 불러오는 방식

💡 동기의 장점

  • 요청과 응답이 순차적으로 이루어지기 때문에 코드의 간결성과 직관성을 유지할 있다.
  • 요청을 보낸 후에 응답을 받아야 다음 작업을 수행하기 때문에 요청과 응답의 순서를 보장

💡  동기의 단점

  • 전체 페이지를 다시 로딩하기 때문에 서버와의 통신량이 많아지고, 자원과 시간이 낭비될 수 있어, 웹페이지의 속도와 성능이 저하될 수 있다. 
  • 화면이 깜빡거리거나 멈추는 현상이 발생하기 때문에 사용자가 불편함을 느껴 사용자 경험이 떨어질 수 있다. 
  • 요청과 응답이 동시에 일어나야 하기 때문에 요청을 보낸 후에는 다른 작업을 할 수 없다. 예를 들어, 네이버 메일에서 메일을 보내는 동안 다른 메일을 읽거나 쓸 수 없다.

 

📝 비동기(Async)?

작업에 대한 요청과 결과를 동시에 실행하지 않아 1번 작업에 대한 요청을 받고 결과를 처리하지 않아도 2번 작업에 대해 요청을 받는 것처럼 중간에 다른 작업이 가능하다. 

  • 작업을 다른 쓰레드에서 시키고, 끝날 때까지 기다리지 않는다. (현재 쓰레드에서 다른 작업을 시작할 수 있다)
  • 요청과 응답이 동시에 일어나지 않고 나중에 응답하는 것
  • 웹페이지를 새로고침하지 않고도 데이터를 불러오는 방식
  • 예를 들어, 네이버 블로그나 카페에서 댓글을 작성하고 작성 버튼을 누르면 페이지 전체가 재로드 되지 않고 댓글 영역 부분만 업데이트 되어 댓글이 적용됨

💡  비동기의 장점

  • 전체 페이지를 다시 로딩하지 않고 필요한 부분만 업데이트하기 때문에 웹페이지의 속도와 성능을 향상시킬 수 있다.
  • 서버와의 통신량이 줄어들고, 자원과 시간을 절약할 수 있다.
  • 화면이 깜빡거리거나 멈추지 않고 부드럽게 작동하기 때문에 사용자 경험을 개선시킬 수 있다. 
  • 요청과 응답이 동시에 일어나지 않아도 되기 때문에 요청을 보낸 후에 다른 작업을 할 수 있다.

💡  비동기의 장점

  • 비동기(Async) 통신은 동기(Sync) 통신보다 코드를 작성하고 이해하는 것이 어려워 코드의 복잡도가 증가할 수 있다.
  • 비동기(Async) 통신은 요청과 응답이 분리되어 있기 때문에, 에러가 발생했을 어떤 요청에서 에러가 발생했는지 파악하고 처리하는 것이 쉽지 않을 있다.
  • 비동기(Async) 통신은 요청을 보낸 후에 응답을 기다리지 않고 다음 작업을 수행하기 때문에, 요청의 처리 속도에 따라 응답이 뒤죽박죽 될 수 있어 요청과 응답의 순서를 보장할 수 없다. (예를 들어, A와 B라는 두 개의 요청을 보냈는데, B의 처리가 더 빨라서 B의 응답이 먼저 도착하는 경우가 있을 수 있다.)

 

 동기(Sync) 비동기(Async)
- 요청과 응답이 동시에 일어난다

- 웹페이지의 전체를 업데이트 한다

- 코드 간결성과 직관성을 유지할 수 있다

- 요청과 응답의 순서를 보장할 수 있다

- 에러 처리가 쉬울 수 있다

- 웹 페이지의 속도와 성능이 저하될 수 있다

- 사용자 경험이 떨어질 수 있다

- 병렬적으로 여러 작업을 수행할 수 없다

- 요청과 응답이 동시에 일어나지 않는다

- 웹 페이지의 일부분만 업데이트한다

- 코드의 복잡도가 증가할 수 있다

- 요청과 응답의 순서를 보장할 수 없다

- 에러처리가 어려울 수 있다

- 웹페이지의 속도와 성능을 향상시킬 수 있다

- 사용자 경험을 개선시킬 수 있다

- 병렬적으로 여러 작업을 수행할 수 있다

 

📝 요약

순서가 중요한 경우엔 동기, 처리 결과에 의존하지 않고 성능적으로 빠른 처리가 필요하다면 비동기를 쓰는 것이 좋다.

웹페이지의 전체적인 구조나 디자인을 바꾸는 경우는 동기, 웹 페이지의 일부만 자주 바뀌는 경우는 비동기를 사용하는 것이 좋다.


💡 비동기처리가 필요한 이유?

네트워크 동신(서버에 데이터를 요청하는 일)은 부하가 많이 걸리는 일

만약에 비동기처리를 하지 않았다고 가정하면, 테이블 뷰를 스크롤 할 때마다 버벅거릴 것임(스크롤이 자연스럽게 일어나지 않고, 뚝뚝 끊길 것이다)

📝 비동기 처리하는 방법1 - Async, Await

Async, Await 이란?

  • 기존 비동기 처리 방식은 DispatchQueue나 completionHandler를 사용하여 처리했지만, 더욱 편하게 비동기 처리할 수 있는 문법
  • Swift 5.5
  • throws와 try가 한 쌍인 것처럼 async와 await가 한 쌍임
  • 컴파일 타임에 concurrency에 대한 문제 파악 가능

(completion handler는 에러일 때 completion handler 호출을 잊어버리는 문제, 동기적으로 수행해야할 비동기 함수 호출이 많으면 코드 depth가 깊어지는 문제, 실패, 성공에 따른 코드 분기가 복잡하다는 문제가 있음)

 

async / await는 비동기 코드를 마치 동기 코드인 것처럼 작성할 수 있기 때문에 동일한 언어 구조를 최대한 활용할 수 있다. 

 

completion handler를 사용한 코드
async/await를 사용한 코드

async/await는 completion handler보다 가독성이 월등히 좋고 간편하다.

 

💡 async

async는 함수가 비동기로 처리된다는 것을 의미한다

func asyncTest() async throws -> String {
	// ...
}

// 프로토콜에서도 요구 가능
protocol SomeProtocol {
    func test() async
}

💡 await

async 함수를 호출하기 위해서는 await 키워드가 필요

await로 마킹된 곳은 potential suspension point(잠재적 일시 중단 지점)로 지정

async로 선언한 함수가 완료될 때까지 일시 중지 되는 지점

(일시 중단 (suspend)  해당 스레드가 다른 동작을 수행할 수 있게 제어권을 놓아주겠다는 의미)

async로 데이터 요청을 하고 await 지점에서 대기하는 것

Task {
    let string: String = try await asyncTest()
    print(string)
}

asyncTest()가 완료될 때까지 해당 Task의 작업은 일시 정지된다.

async 메서드를 호출하려면 async 메서드 내에서 호출되거나, Task로 묶어서 호출해야 한다.

 

✨ Suspend?

await를 만나면 suspend될 수 있다.

일시 중단 (suspend)는 "해당 스레드가 다른 동작을 수행할 수 있게 제어권을 놓아주겠다"는 의미

 

 sync에서의 thread 제어권

A 함수에서 B 라는 동기 함수(sync)를 호출하면, A 함수가 실행되던 스레드의 컨트롤을 B 함수에게 전달한다. 

B 함수가 끝날때까지 해당 스레드는 완전히 점유되어서 다른 일을 수행하지 못하게 된다.

B 함수가 끝나면 다시 A 함수에게 스레드에 대한 컨트롤 돌려준다.

 

 

async에서의 thread 제어권

A 함수에서 B 라는 비동기 함수(async)를 호출하면, A 함수가 실행되던 스레드의 컨트롤을 B 함수에게 전달한다.

B 함수가 완료되면 원래 A 함수에게 컨트롤을 돌려준다

 

하지만 B 함수는 async 함수이기 때문에 중간에 suspend 될 수 있음. (그러면 원래 A 함수도 suspend 됩니다.)

스레드에 대한 제어권 system 에게 가고, 시스템은 스레드를 사용하여 다른 작업을 수행할 수 있게 된다.

시스템이 우선 순위 등을 판단해가면서 여러 작업들을 실행하다가, 어느 시점에 이르면 일시 중단된 비동기 함수를 계속 실행하는 작업이 가장 중요하다고 판단하는 순간이 오면, 그때 해당 함수를 재개(resume)하고, 비동기 함수는 할당 받은 스레드를 제어하고 작업을 계속할 수 있음.

 

 

 

📝 비동기 처리하는 방법2 - DispatchQueue

 

// DispatchQueue 사용한 비동기 처리
DispatchQueue.global.async {

}

 

📝 비동기 처리하는 방법3 completionHandler

 

// completionHandler를 사용한 비동기 처리
let task = URLSession.shared.dataTask(with: url, completionHandler: { data, response, error in

}).resume()

 

'TIL (Today I Learned)' 카테고리의 다른 글

[CS] 리팩토링이란  (0) 2024.02.18
[Swift] MVVM 패턴  (0) 2024.02.17
[Swift] ARC (Automatic Reference Counting)  (0) 2024.02.16
[CS] 객체지향 프로그래밍(OOP)이란?  (0) 2024.02.12
[Swift] Swift란?  (0) 2024.02.12