안녕하세요:) 오늘은 전 편에 이어
네트워크와 관련된 포스팅 2탄입니다!!!!
1탄 Process vs Thread가 궁금하신 분은 보고 오시고 :)
이번 포스팅은 진짜 귀에 딱지 앉도록 들었던
Sync vs Async와 Serial vs Concurrent에 대해 공부해보려고 합니다!!!!!!!!!!
이번엔 이론에 대해서만 공부할 거구!!!!!!!!!!!
실제 iOS에서 어떻게 사용하는진 이후 포스팅 할 거예요!!
개념을 알아야 제대로 쓸 수 있다 생각 하기에 🌝
모든 포스팅은 편의 말투로 합니다~!!
1. Synchronous vs Asynchronous
이번엔 Synchronous와 Asynchronous에 대해 알아보겠움!!!
1-1. Synchronous (동기)
Synchronous라는 것은 사전적 의미로
이런데, "동시 발생하는" 이라는 뜻을 가졌기 때문에,
동시 발생하는데 왜 sync야?? async아니야?? 라는 의문을 가질 수 있음..
근데 여기서 '동시 발생' 이라는 것은 작업이 동시 발생 한단 게 아니라
'요청' - '응답'이 동시 발생한다는 말임!! 풀어 쓰자면,
요청에 대한 응답이 동시에 발생해야 한다
즉, 내 작업이 끝나기 전까진 다른 작업을 수행하지 못한다
라고 이해를 해야함!!!
자, 무슨 말이냐면 우리가 만약
아이패드, 아이폰, 맥북을 애플스토어에서 주문을 하고 싶음
그러면 Synchronous에선
내가 처음에 아이패드를 주문(요청)하면,
아이패드가 나한테 배달(응답) 올 때까지 아이폰, 맥북은 주문할 수 없음 ..ㅎ
왜냐면, 아이패드 주문(요청)-배달(응답)이 동시 발생해야 하기 때문임!
그 사이에 다른 주문(요청)을 할 수 없고든!!
만약 애플이 바뻐서 원래 늦지만 아이패드가 배송오는데 1달이 걸린대 ㅋ
그러면 1달 걸려서 내 품에 배송올 때까지 우린 아이폰, 맥북은 주문조차 할 수 없는거
1달이 걸려서 아이패드가 드디어 내 품으로 오면,
그제야 우린 아이폰을 주문할 수 있고, 이 또한 마찬가지로
아이폰이 나에게 배달 오기까지 맥북은 주문 할 수 없음!
이것을 컴퓨터 작업이라고 생각해보자 :)
위 그림에서 Synchronous에선
1의 작업이 완료 되어야만 다음 작업이 실행되기 하기 때문에
(2작업이 완료되어야 3작업, 3작업이 완료되어야 4작업)
따라서 전체 실행 시간은 45초가 걸리는 것
그럼 Synchronous 너무 비효율적인거 아님? 이라고 생각할 수 있는데
우리가 평소에 별도의 작업 없이 죽죽 써내려 가는 코딩이 Synchronous임
따라서, 만약 오래 걸리는 작업이 있다면 다음에서 배울 Asynchronous로 처리를 해줘야함!
1-2. Asynchronous (비동기)
Asynchronous는 Synchronous와 반대 개념임!!
이또한 "동시에 발생하지 않는" 이라는 말을 풀어쓰자면,
요청에 대한 응답이 동시에 발생하지 않는다
즉, 내 작업이 끝나기 전에 다음 작업을 실행한다
라고 이해를 하면 됨 :)
Synchronous 반대 개념이기 때문에
아이패드, 아이폰, 맥북을 주문한다 했을때
아이패드를 주문(요청)하고난 후, 배송(응답)이 올 때까지 기다리지 않고
바로 아이폰, 맥북을 이어 주문할 수 있는 것임
위에서도 말했지만, 동시에 발생하지 않는다는 것은 어떠한 '작업'이 아니라,
'요청' - '응답'에 대한 것으로 이해해야 함 ㅎㅎ!!!
근데 별다른 응답이 없는 작업이라도 Async면 다음 작업과 동시에 실행되기 때문에,
Async작업이 많아지면 여러 가지 작업을 '동시에' 처리 할 수 있어짐
Asynchronous에선 1작업이 완료되지 않아도 2작업, 3작업, 4작업을 실행할 수 있어,
전체 실행 시간은 가장 오래걸리는 1작업이 끝나는 시간인 20초가 되는 것임!
Asynchronous에서는 요청에 대한 응답이 나중에 오기 때문에
보통 Callback 함수로 들어옴
(응답을 받기 전에 다른 작업들을 계속 할테니까)
1-3. Synchronousvs Asynchronous
Synchronous | Asynchronous | |
정의 | 요청에 대한 응답이 동시에 이루어져야 한다 때문에 모든 작업을 순차적으로 진행한다 |
요청에 대한 결과가 동시에 일어나지 않는다 때문에 모든 작업을 동시에 진행한다 |
장점 | 설계가 매우 간단하고 직관적임 | 응답이 주어질 때까지 기다리지 않고 다른 작업을 하므로 자원을 효율적으로 사용할 수 있다 |
단점 | 응답이 주어질 때까지 아무 것도 못하고 대기해야 한다 | 동기보다 설계가 복잡하다 |
실제 코드를 실행해보면,
Synchronous는 sleep이 3초 끝난 뒤에 print가 출력되고,
Asynchronous는 sleep 작업과 동시 실행되어 print가 바로 출력됨
2. Serial vs Concurrent
이번에는 Serial과 Concurrent에 대해 다뤄보려 함:)
왜 sync, async와 같이 다루냐면,
Sync == Serial
Async == Concurrent
라고 생각하시는 분이 계실까..보..ㅏ..?
엄연히 다른 개념입니다..!!!!!!!!!!!!111!!!!1 뭐가 다른지 써볽게욝
2-1. Serial
먼저, Serial에 대해 사전적 정의를 보면 더 이해가 안갈 것임 ^^;
연속극 말고 형용사를 보면
순 차 적 인
이라고 되어있기 때문임
않이.. Sync도 앞 작업이 끝날 때까지 뒷작업 실행 못하니까.... 순차적인 거 아님?
그럼 Sync랑 Serial이랑 같은 거 아님?????????
이라 말할 수 있겠지만
여기서 포인트가 잘못 되었음
Sync는 앞 작업과 뒷 작업의 연관성에는 상관이 없음..!
무슨 말이냐, Sync는
나는 내 요청에 대한 답을 받을 때까지 기다릴 것이다!
라는 '단일 작업'에 대한 특성을 지칭하는 것임
따라서 앞 작업이 Sync라 해도, 뒷 작업은 Async일 수도 있고 그럼!!!
근데 이 앞 작업과 뒷 작업을 '순차적'으로 실행시킬지 말지 정하는게
바로 이 Serial & Concurrent 개념인 것임
이 Serial은 애플에서 보통 어떤 때 쓰냐면,
GCD 사용할 때 SerialQueue... 이런 식으로 사용함
대표적으로 우리가 사용하는 Main Queue가 SerialQueue임
근데 여러분, Queue가 뭐임? 여러 작업들을 FIFO 하는 것이잖음
따라서 Serial은
내 Queue에 들어온 작업들을 순차적으로 실행 시키겠다
라는 말임
따라서 Sync가 순차적이라는 말은 잘못된 것임
Sync는 단일 작업의 특성 중 하나이고,
이런 단일 작업'들'을 순차적으로 '하나씩'실행하는 것이 Serial임
왜냐면 Serial Queue는 한 번에 하나의 Task만 실행시킬 수 있기 때문 (제일 🌟핵심임)
따라서 Serial Queue를 그림으로 설명하자면 다음과 같음
뭐 이런 그림임 :D
위에서 Async 작업이 있다 해도 Serial Queue는 1개의 Task만 실행할 수 있단 게 포인트!!
그림으로 이해가 갔음 좋겠는데....... ;) 안 될 것 알기에
iOS의 Main Queue가 Serial Queue니까, 코드로 예제를 보여주겠음
print("start")
DispatchQueue.main.async {
for _ in 0...10 {
print("async")
}
}
for _ in 0...10 {
print("sync")
}
print("end")
|
자, 이런 코드가 있을 때 실행결과가 어떻게 나오냐면
이런 식으로 나옴!!!
왜 이런 그림이냐면, Serial Queue이기 때문에, 입 아프게 말하지만
한번에 하나의 Task밖에 실행을 못 하기 때문임!!!
따라서 sync인 'start 프린트' 작업이 먼저 실행되고,
그 다음에 'async 프린트' 작업이 async라서, 그 다음 작업인 'sync 프린트 작업'과
동시에 실행이 되어야 할 것 같지만, Serial Queue는 하.나.의. Task밖.에. 작.업.을. 못.해.서
'sync 프린트', 'end 프린트' 작업을 다 하고 나서야 'async 프린트' 작업이 실행 된 것임!
작업 순서를 그림으로 보자면,
async가 중간에 껴서 실행 순서가 바꼈지만, 위처럼 하나씩 실행됨
만약 sync 만으로 이루어진 작업이면, 순서에 맞춰 그대로 실행됐을 것임!
Serial Queue는 주로 작업을 "동기화" 할 때 사용한다 함
이것이 바로 Serial Queue :-)
2-2. Concurrent
serial을 제대로 이해 했다면 어려울 것 없다고 봄:)
사전적 언어 그대로,
동 시 에 발 생
시키는 것임
이또한 Async와 다른 개념으로, Async가
나는 내 요청에 대한 답을 기다리지 않겠다!
라는 '단일 작업'에 대한 특성을 지칭하는 것이라면
Concurrent는
내 Queue에 들어온 작업들을 동시다발적으로 실행 시키겠다
이런 개념임! 또한 이름 그대로 Serial과 다르게
한 번에 여러 개의 Task를 실행시킬 수 있음 (제일 🌟핵심임)
따라서 그림으로 보자면
뭐 이런 그림임 :)
아까 Serial 예제를 그대로 Concurrent에서 실행시켜 본다면,
(Concurrent Queue는 직접 만들어서 실행해 봐야함. GCD를 모른다면, sync & asyc만 구별하세요!)
let concurrentQueue = DispatchQueue.init(label: "SodeulQueue", attributes: .concurrent)
concurrentQueue.sync { print("start") }
concurrentQueue.async { for _ in 0...5 { print("async") }}
concurrentQueue.sync { for _ in 0...5 { print("sync") } }
concurrentQueue.sync { print("end") }
|
결과가 어떻게 나오냐면
이런 식으로 나옴 :)
이 결과만 보고도 이해가 갔으면 좋겠다만
Concurrent Queue는 한번에 여러 가지 Task를 실행시킬 수 있기 때문에
sync인 start 프린터 함수가 먼저 찍히고,
그다음에 'async 프린트' 작업이 async라서, 그 다음 작업인 'sync 프린트 작업'과
'동시에' 실행이 되는 것임 왜냐? Serial과 달리 한.번.에. 여.러. Task를. 실.행.시킬 수 있으니까!
따라서 'sync 프린트' 작업, end 작업과 'async 프린트' 작업이 동시에 실행되는 것임
작업 순서를 그림으로 보자면
이렇게 실행 되는 것 :)
위 결과로 하나 더 캐치해보자면, Concurrent Queue가 "동시 실행"이긴 하지만,
Sync로 실행한 경우는 현재 작업이 끝날 때까지 다음 Sync 작업을 실행하지 않는 것 같아 보이는데
이부분은 더 실험해보고 추가 하겠음!
Concurrent Queue는 주로 작업을 "수행" 할 때 사용한다 함
이해가 되셨길!
.
.
.
평소에 헷갈리던 개념을 하나씩 정리 중인데
오늘 공붛한 내용이 가장 오래 걸리고 머리아팠네여ㅠㅠㅠ 그만큼 뿌듯하지만
근데 내가 이해한 내용이 틀렸을 수도 있기에 더 찾아보겠습니다 ㅎㅎ
잘못된 내용, 피드백, 환영합니다 :)🌸
'iOS > iOS' 카테고리의 다른 글
iOS) 런 루프(RunLoop) 이해하기 (14) | 2020.12.03 |
---|---|
iOS) GCD (Grand Central Dispatch) (6) | 2020.12.02 |
iOS) 프로세스(Process) vs 쓰레드(Thread) (8) | 2020.12.01 |
iOS) 메모리 저장 방식 - Big Endian / Little Endian (1) | 2020.11.28 |
iOS) APNs :: Push Notification 동작 방식 (15) | 2020.11.24 |