๋ค์ด๋ฒ ๋ธ๋ก๊ทธ/velog ์์ ์์ฑํ๋ ๋ด์ฉ๋ค์ ํฐ์คํ ๋ฆฌ๋ก ํตํฉ์ค์ ๋๋ค :)
๋์์ฑ ํ๋ก๊ทธ๋๋ฐ์ผ๋ก ํ๋ก๊ทธ๋จ ๊ตฌ์ฑํ๊ธฐ
๋ฉ์ธ์ค๋ ๋์ ๊ฒฝ์ฐ UI๊ด๋ จ ์ฌ์ฉ์์ ์ง์ ์ํธ์์ฉํ๋ ์์ ์ ์ฒ๋ฆฌํ๋๋ฐ, ๋ฐ์ดํฐ๋ณํ, ์ด๋ฏธ์ง ์ฒ๋ฆฌ๋ฅผ ๋ฉ์ธ์ค๋ ๋์์ ์ ๋ถ ์ฒ๋ฆฌํ ๊ฒฝ์ฐ ์ฝ๊ฐ์ ๋ฒ๋ฒ ์ ๋ฌธ์ ๊ฐ ๋ฐ์ํ๋ค.
๋ฉ์ธ์ค๋ ๋์ ๊ณผ์คํ๋ ์ ๋ฌด๋ฅผ ๋ฐฉ์งํ๊ธฐ์ํด ๋์จ๊ฒ์ด ๋ฐ๋ก Concurrency(๋์์ฑ)์ด๋ค.
๋์์ฑ ํ๋ก๊ทธ๋๋ฐ์ ์ฌ๋ฌ๊ฐ์ ์ค๋ ๋๋ฅผ ์ฌ์ฉํจ์ผ๋ก์จ ๋์์์ ์ ๊ฐ๋ฅ์ผํ๋ค. ํ์ง๋ง ๋จ์ ๋ ์๋๋ฐ ๋ฐ๋ก thread safety๋ฅผ ์ ์งํ๊ธฐ ์ด๋ ต๋ค๋ ๊ฒ์ด๋ค. ๋ค๋ฅธ ์ค๋ ๋๊ฐ ์์ ํ๋๊ฑธ ์์ฐจ์ ์ผ๋ก ๊ฐ์ ธ์์ ์งํค๊ธฐ๊ฐ ์ด๋ ค์์ง๋ค.
๋์์ฑ ํ๊ฒฝ์์ thread safety๋ฅผ ์ ์งํ๊ธฐ ์ํ ๋ ธ๋ ฅ์ผ๋ก ์ ํ์ GCD ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ๋ง๋ค์ด์ ์ ๊ณตํ๊ณ ์๋ค.
Dispatch Queues and Run Loops
๋์คํจ์น ํ๋ ์์ ์ ๋ํ ์คํ์ ์ฑ์ ๋ฉ์ธ ์ฐ๋ ๋ ํน์ ๋ฐฑ๊ทธ๋ผ์ด๋ ์ฐ๋ ๋์์ ์ง๋ ฌ๋ก ํ ์ง, ๋์์ฑ์ผ๋ก ํ ์ง๋ฅผ ๊ด๋ฆฌํด์ฃผ๋ ๊ฐ์ฒด์ด๋ค.
๋์คํจ์น ํ์ work item์ ์ฐจ๊ณก์ฐจ๊ณก ๋ฃ๊ฒ ๋๋ค. (FIFO์๋ฃ๊ตฌ์กฐ)
์ ๋ฆฌํ์๋ฉด ๋์คํจ์นํ(๋๊ธฐ์ด)์ ์์ ์ ๋ฃ์ด์ฃผ๋ฉด ๋ค๋ฅธ ์ค๋ ๋์ dispatchํ์ฌ ์์ ์ ๋๋ธ ํ ๋ฉ์ธ์ค๋ ๋๋ก ๋์์จ๋ค. ์ด ๋ฐฉ๋ฒ์ ํตํด ๋ฉ์ธ์ค๋ ๋์ ๊ณผ๋ถํ๋ฅผ ๋ฐฉ์งํ ์ ์๋ค.
GCD๋ฅผ ์ ์ฉํ๊ธฐ ์ ์๋ ๋ฐ์ดํฐํ๋ก์ฐ๊ฐ ๋ ๋ฆฝ์ ์ผ๋ก ์ด๋ฃจ์ด์ก์๊ฒ์ด๋ค. ์ด๋ฌํ ๋ ๋ฆฝ์ ์ธ ๋ฐ์ดํฐ ํ๋ก์ฐ๋ฅผ GCD๋ก ๋ฌถ์ด์ค ์ ์๋ค.
์ด๋ ๊ฒ ๋ฌถ์ด์ฃผ๋ฉด ๊ธฐ์กด์ ๋ ๋ฆฝ์ ์ธ ๋ฐ์ดํฐ ํ๋ก์ฐ๊ฐ Chaining์ด์๋ค๋ฉด GCD๋ ๋ฐ์ดํฐ ๊ด๋ฆฌ๋ฅผ Grouping work์ผ๋ก ๊ด๋ฆฌํ๊ฒ๋๋ค.
์ค๋ ๋๋ณ ์์ ๊ทธ๋ฃนํ์ ๋ค์์์๋ก ์งํ๋๋ค
๋จผ์ ๋์คํจ์น๊ทธ๋ฃน ๊ฐ์ฒด๋ฅผ ๋ง๋ ๋ค
→ ๊ทธ๋ฃนํํ ํ ์ต์ ๋ ํ๋ผ๋ฏธํฐ์ ๊ทธ๋ฃน ๊ฐ์ฒด๋ฅผ ๋ฃ๋๋ค
→ ๋๋ค๋ฅธ ๊ทธ๋ฃนํํ ํ ์ต์ ๋ ํ๋ผ๋ฏธํฐ์ ๊ทธ๋ฃน๊ฐ์ฒด๋ฅผ ๋ฃ์ด์ฃผ์ด ๋ฌถ๋๋ค
→ ๋ง์ง๋ง์ผ๋ก ๊ทธ๋ฃนํ ์์ ๋ค์ด ๋๋๋ฉด ๋ฉ์ธ์ค๋ ๋์ ์์ ๋๋ฌ๋ค๊ณ ์๋ ค์ค notify๋ฅผ ๋ฃ๋๋ค
subsystem๋ค์ ํ์ค๋ก ์ธ์๋ณด์ .sync ๋ฉ์๋๋ฅผ ์ด์ฉํ๋ฉด ๊ฐ๋จํ๊ฒ ์ธ์ธ ์ ์๋ค. ์ด๋ ๊ฒ ํ์ค๋ก ์ธ์ฐ๋ฉด ๋ฐ๋๋ฝ ํ์์ ๋ฐฉ์งํ ์ ์๋ค.
Quality of Service
์ ํ์ QoS ํด๋์ค๋ฅผ ํตํด ์์ ์ ์ฐ์ ์์๋ฅผ ๋๋ ์ ์๋ ๊ธฐ๋ฅ์ ์ ๊ณตํ๋ค IO ์ค์ผ์ฅด๋ง ์ฐ์ ์์์ ๋ฐ๋ผ ๊ฐ๋ฐ์๋ ๋ค์ํ๊ฒ ์์ ์ ์ฐ์ ์์๋ฅผ ๋ถ์ฌํ์ฌ ๋ค๋ฅธ ์ค๋ ๋๋ก ์์ ์ ๋ณด๋ผ ์ ์๋ค.
async ๋ฉ์๋์ QoS ํ๋ผ๋ฏธํฐ๋ฅผ ํตํด ์์ ์ ์ฐ์ ์์๋ฅผ ์ ํด์ค ์ ์๋ค
DispatchWorkItem
let myQueue = DispatchQueue(label: "com.nil.queue")
let workItem = DispatchWorkItem {
print("WorkItem task")
}
myQueue.async(execute: workItem)
print("========")
Dispatch work item์ Task๋ฅผ ์บก์ํํ๋๋ฐ ์ด์ฉํ๋ ํด๋์ค์ด๋ค item ๊ฐ์ฒด๋ก ๋ฌถ์ด์ ๋์คํจ์น ํ์ ๋ฃ์ ์ ์๋ค. ๊ทธ๋ฃนํํด์ ์ฌ์ฉ๋ ๊ฐ๋ฅํ๋ค
let workItem = DispatchWorkItem(qos: .userInitiated, flags: .assignCurrentContext) {
// Your task here
}
let queue = DispatchQueue(label: "com.example.queue", qos: .background)
queue.async(execute: workItem)
๋ํดํธ๊ฐ์ผ๋ก async๋ ์คํ๋ ๋์ qos๋ฅผ ์บก์ณํ๋ค ํ์ง๋ง DispatchworkItem์ ์ฝ๋ ์์ฑ ์์ ์ ๊น๋ฐ์ ๊ฝ์์ qos๋ฅผ ์ง์ ํด์ค ์ ์๋ค ๋ฐ๋ผ์ ์์ queue ๊ฒฝ์ฐ .userInitiated๋ก ํ๊ฐ ์คํ๋๋ค.
.wait ๋ฉ์๋๋ฅผ ํตํด ๊ผญ ๊ฒฐ๊ณผ๋ฌผ์ด ํ์ํ ์์ดํ (์์ )์ ๊ธฐ๋ค๋ ค์ค ์ ์๋ค
DispatchWorkItem์ ๊ธฐ๋ค๋ ค์ฃผ๋ ๊ธฐ๋ฅ์ ํตํด ์ ๋ณด์ ownership์ ๋ถ์ฌํ ์ ์๋ค
๊ธฐ์กด์ ์ธ๋งํฌ์ ๊ทธ๋ฃน๊ณผ์ ๊ฒฐ์ ์ ์ธ ์ฐจ์ด๋ ๋ฐ๋ก ์ด๋ฌํ ownership์ ๊ฐ์ง ์ ์๋ค๋ ๊ฒ์ด๋ค
Shared State Synchronization
์ ์ญ๋ณ์๋ atomic ํ๊ฒ ์ด๊ธฐํ๋๋ค.
ํ์ง๋ง ํด๋์ค ํ๋กํผํฐ๋ ์ํ ๋ฏนํ์ง ์๋ค
๋ ์ด์ง ํ๋กํผํฐ ๋ํ ์ํ ๋ฏนํ๊ฒ ์ด๊ธฐํ๋์ง ์๋๋ค (race condition ์ด์)
class BankAccount {
var balance: Double = 0.0
func deposit(amount: Double) {
balance += amount
}
func withdraw(amount: Double) {
if balance >= amount {
balance -= amount
} else {
print("Insufficient funds!")
}
}
}
BankAccount ํด๋์ค๋ Atomicํ์ง๋ง balance๋ ๊ทธ๋ ์ง์๋ค. ๋ฐ์ดํฐ๊ฒฝ์์ด ์ผ์ด๋ ์ ์๊ธฐ ๋๋ฌธ์ด๋ค
Atomic ํ์ง ์๋ค๋ฉด ์ด๋ค ์ํฉ์ด ๋ฐ์ํ ์ ์์๊น? ๋ค์๊ณผ ๊ฐ์ ์ํฉ์ ๊ฐ์ ํด๋ณด์
ThreadA๋ 800๋ฌ๋ฌ๋ฅผ ์ธ์ถํ๋ค
ThreadB๋ 500๋ฌ๋ฌ๋ฅผ ์ธ์ถํ๋ค
์ค๋ ๋A์ B๋ ๋์์ ์ธ์ถ์ 1000๋ฌ๋ฌ์ธ ๊ฒ์ ํ์ธํ ํ ์์ฌํ๋ฉฐ ๋์ ๋บ๋ค
ํ์ง๋ง ๊ฒฐ๊ณผ์ ์ผ๋ก๋ -300๋ฌ๋ฌ๋ก ๋์ด๋ฒ๋ฆฐ๋ค
์ด๋ ๊ฒ ๋ค์์ ์ค๋ ๋๊ฐ ์ ๊ทผํด์ get/set์ ํด๋ฒ๋ฆด ๊ฐ๋ฅ์ฑ์ด ์์ ๋ atomic ํ์ง ์๋ค๊ณ ํ๋ค
class ThreadSafeBankAccount {
private var _balance: Double = 0.0
private let balanceQueue = DispatchQueue(label: "balanceQueue")
var balance: Double {
return balanceQueue.sync { _balance }
}
func deposit(amount: Double) {
balanceQueue.sync {
_balance += amount
}
}
func withdraw(amount: Double) {
balanceQueue.sync {
_balance -= amount
}
}
}
์์ ๊ฐ์ ๋ฌธ์ ์ ์ .sync ๋ฉ์๋๋ฅผ ํตํด ๋๊ธฐํํจ์ผ๋ก์ ๋ฐฉ์งํ ์ ์๋ค.
์ค๋ ๋๋ค์ด ํ๋์ balanceQueue๋ฅผ ํตํด ์ ๊ทผํจ์ผ๋ก์จ ์์๋๋ก ๋ฐ์ดํฐ๋ฅผ get/set ์ ์งํํ๋ค
class DatabaseManager {
lazy var connection: DatabaseConnection = {
print("Establishing connection...")
return DatabaseConnection()
}()
}
๋ ์ด์ง ํ๋กํผํฐ ๋ํ ์ํ ๋ฏนํ์ง ์๋ค ์ค๋ ๋A์ ์ค๋ ๋B๊ฐ ์ปค๋ฅ์ ์ ์ ๊ทผํ ๋ ํ๋ฆฐํธ๊ฐ ๋๋ฒ์ฐํ๋ ๊ฒ์ ๋ณผ ์ ์๋ค ์ฆ ๊ฐ์ ํ๋กํผํฐ๊ฐ ์ค๋ณต๋์ด ๋์๊ฐ๊ณ ์๋ค๋ ๋ป์ด๋ค
Use GCD for Synchronization
์์ ๊ฐ์ด ์๋ก๋ค์ด์ค๋ ์ํ๋ฅผ .sync์ ๋ฃ์ด์ค์ผ๋ก์จ ๋ฐ์ดํฐ ๊ฒฝ์์ ๋ฐฉ์งํ ์ ์๋ค.
์์ ์์ดํ ๋ค์ ์ด๋ ํ์ ๋ค์ด๊ฐ๊ฒํ๊ณ ์ด๋ ํ์๋ ์ ๋ ์๋ค์ด๊ฐ๋์ง ๋ฏธ๋ฆฌ ์์ ๊ฐ์ ์ฝ๋๋ก ์ ํด์ค ์ ์๋ค..
onQueue: ์ด ํ๋ก ๋ค์ด์ ^^
notOnQueue: ์ฌ๊ธด ์ผ์ฌ๋ ํ์ง๋ง ^^
๋์์ฑ ์ธ๊ณ์์ ๊ฐ์ฒด์ ์๋ช ์ฃผ๊ธฐ
→ ๋จผ์ Setup์ ํตํด object๋ฅผ Creating ํ๋ค
→ ๋ง๋ค์ด์ง object๋ฅผ activate ํ๋ค
→ ๋์์ค์ธ stateMachine์ invalidate ํด์ค๋ค.
→ ์ค๋ ๋ ๋ฉ๋ชจ๋ฆฌ์์ ํด์ ํ๋ค
'๐ฆ Flutter' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
Swift ์์ Key-Value Observing ์ด๋? (0) | 2024.06.24 |
---|---|
์์ ฏ์ Key ๋ฅผ ์ฌ์ฉํด์ผํ๋ ์ด์ (0) | 2024.06.12 |
Flutter ํ๋ฉด์ ํ์์ routes ์ onGenerateRoute ์ ์ฐจ์ด (0) | 2024.06.04 |
๋ฐ์ดํฐ ๋ฐ์ธ๋ฉ๊ณผ Reactive X (0) | 2024.06.03 |
Hot Observable & Cold Observable (0) | 2024.06.01 |