λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°
πŸ–₯ Computer Science/Operating System

[OS] 동기와 비동기 그리고 직렬과 λ™μ‹œλŠ” λ¬΄μ—‡μΌκΉŒ?(Sync vs Async & Serial vs Concurrent)

by Fomagran πŸ’» 2021. 5. 31.
728x90
λ°˜μ‘ν˜•

 

μ•ˆλ…•ν•˜μ„Έμš” FomaπŸ‘Ÿ μž…λ‹ˆλ‹€!

였늘 μ“°λ ˆλ“œλ₯Ό 고수(?)처럼 μ΄μš©ν•˜κΈ° μœ„ν•œ κΈ°λ³Έ 지식인 동기와 비동기 그리고 직렬과 λ™μ‹œμ— λŒ€ν•΄μ„œ

 

정리해보도둝 ν•˜κ² μŠ΅λ‹ˆλ‹€.

 

λ°”λ‘œ μ‹œμž‘ν• κ²Œμš”~


Sync(동기)

 

λ™κΈ°μ˜ λœ»μ€ 말 κ·ΈλŒ€λ‘œ λ™μ‹œμ— μΌμ–΄λ‚œλ‹€λŠ” λœ»μž…λ‹ˆλ‹€.

 

이 뜻 λ•Œλ¬Έμ— 더 ν—·κ°ˆλ¦¬κΈ°λ„ ν•˜λŠ”λ°μš”.

 

λ™κΈ°λ‘œ μž‘μ—…μ„ ν–ˆμ„λ• λ™μ‹œμ— μΌμ–΄λ‚˜μ§€ μ•Šκ³  μ°¨λ‘€λŒ€λ‘œ μΌμ–΄λ‚˜μ£ ?

 

그러면 λ„λŒ€μ²΄ 뭐가 λ™μ‹œμ— μΌμ–΄λ‚œλ‹€λŠ” κ²ƒμΌκΉŒμš”?

 

λ°”λ‘œ μš”μ²­κ³Ό μ‘λ‹΅μž…λ‹ˆλ‹€.

 

κ·ΈλŸ¬λ‹ˆκΉ "λ‚΄κ°€ 이거 ν•˜λΌκ³  μ§€μ‹œν–ˆμœΌλ©΄ λλ‚Όλ•ŒκΉŒμ§€ 아무것도 ν•˜μ§€λ§ˆ! μš”μ²­μ„ ν–ˆμœΌλ©΄ λ™μ‹œμ— 응닡해!" 이런 뜻이죠..

 

일반적인 μ½”λ“œλ₯Ό μž‘μ„±ν• λ©΄ μž‘μ„±ν•œ μˆœμ„œλŒ€λ‘œ 호좜되죠? 

 

μ•„λ¬΄λŸ° μ„ΈνŒ…μ„ 해놓지 μ•Šμ€ 경우 보톡 λ™κΈ°λ‘œ μž‘μ—…μ΄ μ§„ν–‰λ©λ‹ˆλ‹€.

 

func μž‘μ—…1() {
    print("μž‘μ—…1 μ‹œμž‘")
    Thread.sleep(forTimeInterval: 3)
    print("μž‘μ—…1 끝")
}

func μž‘μ—…2() {
    print("μž‘μ—…2 μ‹œμž‘")
    Thread.sleep(forTimeInterval: 2)
    print("μž‘μ—…2 끝")
}

func μž‘μ—…3() {
    print("μž‘μ—…3 μ‹œμž‘")
    Thread.sleep(forTimeInterval: 1)
    print("μž‘μ—…3 끝")
}

μž‘μ—…1()
μž‘μ—…2()
μž‘μ—…3()
//μž‘μ—…1 μ‹œμž‘
//μž‘μ—…1 끝
//μž‘μ—…2 μ‹œμž‘
//μž‘μ—…2 끝
//μž‘μ—…3 μ‹œμž‘
//μž‘μ—…3 끝

 

μ΄μ „μ˜ μž‘μ—…μ΄ 아무리 μ˜€λž˜κ±Έλ €λ„ λλ‚ λ•ŒκΉŒμ§€ λ‹€μŒ μž‘μ—…μ΄ μ§„ν–‰λ˜μ§€ λͺ»ν•˜μ£ .

 


Async(비동기)

 

동기와 λ°˜λŒ€λ‘œ λ™μ‹œμ— μΌμ–΄λ‚˜μ§€ μ•ŠλŠ” 것이겠죠?

 

μœ„μ—μ„œ λ™κΈ°λŠ” μš”μ²­κ³Ό 응닡이 λ™μ‹œμ— μΌμ–΄λ‚˜λŠ” 것이라고 ν–ˆμŠ΅λ‹ˆλ‹€.

 

λΉ„λ™κΈ°λŠ” μš”μ²­κ³Ό 응닡이 λ™μ‹œμ— μΌμ–΄λ‚˜μ§€ μ•Šμ•„λ„ λ©λ‹ˆλ‹€.

 

μš”μ²­μ„ ν•˜λ©΄ μ¦‰μ‹œ 응닡을 ν•˜λŠ” 것이 μ•„λ‹ˆλΌ 응닡은 λ‚˜μ€‘μ— ν•˜κ±°λ‚˜ μ•„λ‹ˆλ©΄ 응닡이 λ˜μ§€ μ•Šμ„ μˆ˜λ„ μžˆμŠ΅λ‹ˆλ‹€.

 

κ·ΈλŸ¬λ‹ˆκΉ "λ„ˆ 이 μž‘μ—… λͺ»ν•΄λ„ λ˜λ‹ˆκΉ 일단 해봐 그리고 λλ‚˜λ©΄ μ•Œλ €μ€˜" 라고 μ§€μ‹œλ₯Ό ν•˜λŠ” 것이죠.

 

let queue1 = DispatchQueue(label: "1")
let queue2 = DispatchQueue(label: "2")
let queue3 = DispatchQueue(label: "3")

func μž‘μ—…1() {
    print("μž‘μ—…1 μ‹œμž‘")
    Thread.sleep(forTimeInterval: 3)
    print("μž‘μ—…1 끝")
}

func μž‘μ—…2() {
    print("μž‘μ—…2 μ‹œμž‘")
    Thread.sleep(forTimeInterval: 2)
    print("μž‘μ—…2 끝")
}

func μž‘μ—…3() {
    print("μž‘μ—…3 μ‹œμž‘")
    Thread.sleep(forTimeInterval: 1)
    print("μž‘μ—…3 끝")
}

queue1.async {
    μž‘μ—…1()
}
queue2.async {
    μž‘μ—…2()
}
queue3.async {
    μž‘μ—…3()
}

 

μ•„λž˜μ™€ 같이 μ‹œκ°„μ΄ μ–Όλ§ˆλ‚˜ 걸리든 λ™μ‹œμ— μ‹œμž‘μ„ ν•˜κ³  μž‘μ—…μ΄ λΉ λ₯Έ 순으둜 λλ‚˜κ²Œ λ©λ‹ˆλ‹€.

 

 

 

근데 μ €λŠ” 이런 의문이 μƒκΈ°λ”λΌκ΅¬μš”.

 

μ•„λž˜ μ½”λ“œμ²˜λŸΌ 싀행해도 "λΉ„λ™κΈ°λ‹ˆκΉ λͺ¨λ‘ μ‹œμž‘μ΄ 되고 μž‘μ—…μ΄ λΉ λ₯Έ 순으둜 λλ‚˜κ²Œ λ˜μ•Όν•˜λŠ”κ±° μ•„λ‹Œκ°€?"

DispatchQueue.main.async {
    μž‘μ—…1()
}

DispatchQueue.main.async {
    μž‘μ—…2()
}

DispatchQueue.main.async {
    μž‘μ—…3()
}

ν•˜μ§€λ§Œ κ²°κ³ΌλŠ” λ™κΈ°μ²˜λŸΌ μž‘λ™ν•©λ‹ˆλ‹€.

μ™œ μ΄λ ‡κ²Œ κ²°κ³Όκ°€ λ‚˜μ˜¬κΉŒμš”?

 

λ°”λ‘œ λ³΄ν†΅μ˜ 경우 큐가 직렬둜 μ„€μ •λ˜μ–΄ 있기 λ•Œλ¬Έμ΄μ£ .


Serial(직렬)

 

κ·Έλ ‡λ‹€λ©΄ 직렬은 무엇을 μ˜λ―Έν• κΉŒμš”?

 

순차적으둜 μ§„ν–‰ν•œλ‹€λŠ” κ²ƒμž…λ‹ˆλ‹€.

 

근데 μ—¬κΈ°μ„œ μ „ λ™κΈ°λž‘ ν—·κ°ˆλ¦¬λ”λΌκ΅¬μš”.

 

 "λ™κΈ°λ‘œ μž‘μ—…μ„ 진행해야 순차적으둜 μ§„ν–‰λ˜λŠ”κ±° μ•„λ‹ˆμ•Ό? λΉ„λ™κΈ°λ‘œ μž‘μ—…ν•˜λ©΄ λλ‚˜λŠ” μ‹œκ°„μ΄ λ‹€ λ‹€λ₯΄κΈ° λ•Œλ¬Έμ— μˆœμ°¨μ μ΄μ§€ μ•Šμ€κ±°μž–μ•„." 

 

"그러면 직렬이 동기고 병렬이 비동기 μ•„λ‹Œκ°€?"

 

라고 μƒκ°ν–ˆμ—ˆμŠ΅λ‹ˆλ‹€...

 

ν•˜μ§€λ§Œ 순차적으둜 μ§„ν–‰ν•œλ‹€λŠ” 말은 "μž‘μ—…"듀을 순차적으둜 μ§„ν–‰ν•œλ‹€λŠ” κ²ƒμž…λ‹ˆλ‹€.

 

μ΄λ ‡κ²Œ λ§ν•˜λ©΄ μ΄ν•΄ν•˜κΈ° νž˜λ“œμ‹€κ±°μ—μš”..

 

κ·ΈλŸ¬λ‹ˆκΉ λ™κΈ°λ‘œ μž‘μ—…ν•  μˆ˜λ„ 있고 λΉ„λ™κΈ°λ‘œ μž‘μ—…ν•  μˆ˜λ„ 있겠죠?

 

"μ–΄λ–€ λ°©μ‹μœΌλ‘œ μž‘μ—…ν•΄λ„ μƒκ΄€μ—†λŠ”λ° λŒ€μ‹  μ°¨λ‘€μ°¨λ‘€ ν•΄!" λΌλŠ” 것이죠.

 

μœ„μ—μ„œ λ³Έ μ½”λ“œλ₯Ό 보면 λΉ„λ™κΈ°λ‘œ 된 μž‘μ—…μ΄ 3개 μžˆμŠ΅λ‹ˆλ‹€.

 

ν•˜μ§€λ§Œ λΉ„λ™κΈ°λ‘œ 됐든 λ™κΈ°λ‘œ 됐든 기본인 직렬큐에 λ‹΄κ²¨μžˆκΈ° λ•Œλ¬Έμ— μ°¨λ‘€μ°¨λ‘€ ν˜ΈμΆœλ˜λŠ” 것이죠!

//μž‘μ—…1
DispatchQueue.main.async {
    μž‘μ—…1()
}

//μž‘μ—…2
DispatchQueue.main.async {
    μž‘μ—…2()
}

//μž‘μ—…3
DispatchQueue.main.async {
    μž‘μ—…3()
}

 

이것은 νμ•ˆμ— μžˆλŠ” μž‘μ—…λ“€μ„ λœ»ν•˜λŠ” 것이지 λ‹€λ₯Έ μ“°λ ˆλ“œμ— μ‹€ν–‰λ˜λŠ” μž‘μ—…μ„ μ˜λ―Έν•˜λŠ” 것은 μ•„λ‹ˆμ—μš”.

 

μ΄λ ‡κ²Œ 각각 queue1,queue2,queue3 λ‹€λ₯Έ νμ—μ„œ λ‹€λ₯Έ μ“°λ ˆλ“œλ‘œ λ™μž‘ν•œλ‹€λ©΄ λΉ„λ™κΈ°λ‘œ λͺ¨λ‘ ν•œλ²ˆμ— μ‹œμž‘ν•  수 μžˆλŠ”κ²ƒμ΄μ£ .

queue1.async {
    μž‘μ—…1()
}
queue2.async {
    μž‘μ—…2()
}
queue3.async {
    μž‘μ—…3()
}

Concurrent(λ™μ‹œ)

 

말 κ·ΈλŒ€λ‘œ λ™μ‹œμ— μž‘μ—…μ„ μ§„ν–‰ν•œλ‹€λŠ” λœ»μž…λ‹ˆλ‹€.

 

직렬은 순차적으둜 "μž‘μ—…"듀을 μ§„ν–‰ν•œλ‹€λ©΄ λ™μ‹œλŠ” 정말 λ™μ‹œμ— μž‘μ—…μ„ μ§„ν–‰ν•©λ‹ˆλ‹€.

 

λ™μ‹œλ‘œ 된 큐λ₯Ό λ§Œλ“€κΈ° μœ„ν•΄μ„  attributes에 .concurrent라고 μ„€μ •ν•΄μ£Όμ‹œλ©΄ λ©λ‹ˆλ‹€.

let concurrentQueue = DispatchQueue(label:"ConcurrentQueue1",attributes: .concurrent)
...

concurrentQueue.async {
        μž‘μ—…1()
}

concurrentQueue.async {
        μž‘μ—…2()
}

concurrentQueue.async {
        μž‘μ—…3()
}

//μž‘μ—…1 μ‹œμž‘
//μž‘μ—…2 μ‹œμž‘
//μž‘μ—…3 μ‹œμž‘
//μž‘μ—…3 끝
//μž‘μ—…2 끝
//μž‘μ—…1 끝

μœ„ μ½”λ“œλ₯Ό 싀행해보면 κ²°κ³ΌλŠ” λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.

 

큐 μ•ˆμ— μžˆλŠ” μž‘μ—…λ“€μ„ λ™μ‹œμ— μ‹€ν–‰ν•΄λ²„λ¦¬λŠ” 것이죠.

 

 

κ·Έλ ‡λ‹€λ©΄ λ™μ‹œνλ₯Ό λ™κΈ°λ‘œ μ‹€ν–‰μ‹œν‚€λ©΄ μ–΄λ–»κ²Œ λ κΉŒμš”?

 

μ €μ˜ μ˜ˆμƒμ€ 동기와 비동기 λͺ¨λ‘ λ˜‘κ°™μ€ κ²°κ³Όκ°€ λ‚˜μ˜¬μ€„ μ•Œμ•˜μŠ΅λ‹ˆλ‹€.

 

"동기든 비동기든 λ™μ‹œμ— μž‘μ—…μ„ ν•˜λ‹ˆ μ‹œμž‘λ„ λ˜‘κ°™μ•„μ•Ό λ˜μ§€ μ•Šμ„κΉŒ?"

 

라고 μƒκ°ν–ˆμŠ΅λ‹ˆλ‹€.

 

concurrentQueue.sync {
        μž‘μ—…1()
}

concurrentQueue.sync {
        μž‘μ—…2()
}

concurrentQueue.sync {
        μž‘μ—…3()
}

//μž‘μ—…1 μ‹œμž‘
//μž‘μ—…1 끝
//μž‘μ—…2 μ‹œμž‘
//μž‘μ—…2 끝
//μž‘μ—…3 μ‹œμž‘
//μž‘μ—…3 끝

 

ν•˜μ§€λ§Œ κ²°κ³ΌλŠ” μ§λ ¬νμ—μ„œ λ™κΈ°λ‘œ μ‹€ν–‰ν•œ κ²ƒμ΄λž‘ λ˜‘κ°™μ•˜μŠ΅λ‹ˆλ‹€.

 

 

λ™μ‹œμ— μž‘μ—…μ„ μ‹€ν–‰ν•œλ‹€κ³  해도 쀑간에 λ™κΈ°λ‘œ 된 μž‘μ—…μ΄ μžˆμœΌλ‹ˆ μš”μ²­μ— λŒ€ν•œ 응닡을 ν•˜κ³  κ·Έ λ‹€μŒμœΌλ‘œ μ‹€ν–‰λ˜λŠ” 것 κ°™μŠ΅λ‹ˆλ‹€.


정리

 

동기와 λΉ„λ™κΈ°λŠ” 각 μ“°λ ˆλ“œμ˜ μž‘μ—…μ— λŒ€ν•œ μš”μ²­μ„ λ™μ‹œμ— 응닡할 것이냐 μ•„λ‹ˆλƒλ₯Ό μ˜λ―Έν•œλ‹€.

 

직렬과 λ™μ‹œλŠ” 큐 μ•ˆμ— μžˆλŠ” μž‘μ—…λ“€μ„ 순차적으둜 진행할 것이냐 λ™μ‹œμ— 진행할 것이냐λ₯Ό μ˜λ―Έν•œλ‹€.

 

즉,λΉ„λ™κΈ°λ‘œ μž‘μ—…λ˜λ”λΌλ„ 직렬큐 μ•ˆμ— 속해 있으면 순차적으둜 μ‹€ν–‰ν•˜κ³ ,

 

λ™μ‹œν μ•ˆμ—μ„œ λ™μ‹œμ— μž‘μ—…μ΄ μ‹€ν–‰λ˜λ”λΌλ„ λ™κΈ°λ‘œ 된 μž‘μ—…μ΄ 있으면 μš”μ²­μ— λŒ€ν•œ 응닡을 끝내고 λ‹€μŒ μž‘μ—…μœΌλ‘œ λ„˜μ–΄κ°„λ‹€.

728x90
λ°˜μ‘ν˜•

λŒ“κΈ€