λ°˜μ„±λ¬Έ

올 ν•œν•΄μ—λŠ” 개인적으둜 λ§Žμ€ 일듀이 μžˆμ—ˆμŠ΅λ‹ˆλ‹€. ν•΄μ˜ μ‹œμž‘μ€ μ΄μ§μ€€λΉ„λ‘œ λΆ€ν„° μ‹œμž‘λ˜μ—ˆκ³  TL둜 마무리 μ§€μ–΄μ•Όν•˜λŠ” ν”„λ‘œμ νŠΈλ“€λ„ μžˆμ—ˆμŠ΅λ‹ˆλ‹€. ν˜„μž¬λŠ” μƒˆλ‘œμš΄ 직μž₯μ—μ„œ 비ꡐ적 ν•˜λ˜ μΌκ³ΌλŠ” λ‹€λ₯Έ λ‹€μ–‘ν•œ ν”Œλž«νΌμ„ λ§‘μœΌλ©΄μ„œ μΌν•˜κ³  μžˆλŠ”λ° λ³‘νŠΉλ„ μ‹œμž‘ν•˜κ³  νšŒμ‚¬μΌλ„ 맀우 λ°”λΉ μ„œ 항상 ν•‘κ³„λŒ€λ©΄μ„œ 또 슀슀둜 κ³΅λΆ€ν•΄μ•Όν•˜λŠ” λ°©ν–₯도 살짝 μžƒμ–΄μ„œ λΈ”λ‘œκΉ…μ„ κ²Œμ„λ¦¬ ν–ˆμŠ΅λ‹ˆλ‹€.

이 λΈ”λ‘œκ·ΈλŠ” 슀슀둜 무언가 깊게 κ³΅λΆ€ν•˜κ±°λ‚˜ μ‹€ν—˜ν•΄λ³΄κ³  λ‚œ κ²°κ³Όλ₯Ό μ΄μ•ΌκΈ°ν•˜κ³  μ‹Άμ—ˆμ§€λ§Œ μ΅œκ·Όμ— κ³΅λΆ€ν•˜λŠ” RLμ΄λ‚˜ μ•Œκ³ λ¦¬μ¦˜ μͺ½μ€ λ‚΄κ°€ 잘 μ•ˆλ‹€κ³  ν• λ§Œν•œ μž…μž₯이 μ•„λ‹Œκ²ƒ κ°™μ•„μ„œ μ“°κΈ° μ’€ λΆ€λ„λŸ¬μ›Œ κΈ€ 쓰기도 νšŒν”Όν•˜κ²Œ 되고 μ•ˆ μ“°λ‹€ λ³΄λ‹ˆ λΈ”λ‘œκ·Έμ™€ 거리가 멀어진것 κ°™μŠ΅λ‹ˆλ‹€.

κ·Έλž˜λ„ μ›λž˜λΆ€ν„° 써였던 도메인도 슬슬 λ§Œλ£ŒκΈ°κ°„μ΄ λ‹€κ°€μ™€μ„œ 이전뢀터 λ°”κΎΈκ³  μ‹Άμ—ˆλ˜ .kr 도메인도 버렸고, 연말을 λ§žμ•„μ„œ λ§ˆμŒμ„ 가닀듬고 이전에 μž‘μ„±ν–ˆλ˜ 글을 정리해 올리고, μ•žμœΌλ‘œλŠ” 쑰금 더 κ°€λ²Όμš΄ μ£Όμ œλ„ κ°€λ³κ²Œ μ“Έ 수 μžˆλ„λ‘ ν•˜κ³  배우고 λŠκΌˆλ˜κ²ƒλ“€μ— λŒ€ν•΄μ„œλ„ κ°„λ‹¨νžˆ 적어보도둝 ν•˜λ €ν•©λ‹ˆλ‹€. 사싀 이전에 μ μ—ˆλ˜ 글듀이 글을 처음 μ¨λ³΄λŠ” μž…μž₯이기도 ν–ˆκ³  λ²ˆμ—­νˆ¬μΈκ²ƒλ„ 많고 (μ§€κΈˆμ΄λΌκ³  λ‹€λ₯Έκ±΄ μ•„λ‹ˆμ§€λ§Œ) λ―Έμˆ™ν–ˆλ˜ 점듀이 λ§Žμ•„μ„œ μ’€ μˆ˜μ • λ³΄μ™„ν•˜λŠ” μž‘μ—…λ„ 진행해보고 μ‹Άμ§€λ§Œβ€¦ 이건 μ‹œκ°„μ΄ 많이 λ“€μ–΄μ„œ μ–΄λ–»κ²Œ 될지 λͺ¨λ₯΄κ² λ„€μš”. κ·Έλž˜λ„ κ΄€λ ¨ ν‚€μ›Œλ“œλ‘œ κ²€μƒ‰ν•˜λ©΄ 맞좀 검색인지 λͺ¨λ₯΄κ² μ§€λ§Œ 상단 λ…ΈμΆœλ˜μ–΄μ„œ (…) λΆ€λ„λŸ¬μ›Œμ„œλΌλ„ 고쳐볼까 ν•©λ‹ˆλ‹€.

λ³Έλ¬Έ

ν•œ CPU에 μ—¬λŸ¬ μ½”μ–΄κ°€ μžˆλŠ” multi-core ν˜•νƒœμ˜ ν”„λ‘œμ„Έμ„œκ°€ μ‚°μ—… ν‘œμ€€μ΄ λ˜λ©΄μ„œ ν•œλ²ˆμ— ν•˜λ‚˜μ˜ μž‘μ—…μ„ μ²˜λ¦¬ν•˜μ§€ μ•Šκ³  μž‘μ—…μ„ λ‹€μ€‘μœΌλ‘œ μ²˜λ¦¬ν•˜λŠ”(multitasking) 것은 μ•„μ£Ό μ˜€λž˜μ „λΆ€ν„° μ‚¬μš©λ˜μ—ˆκ³  κ΅¬ν˜„ν•˜λŠ” 방법도 맀우 λ‹€μ–‘ν•©λ‹ˆλ‹€. μ—”μ§€λ‹ˆμ–΄κ°€ κ°€μž₯ μ‰½κ²Œ multitasking을 κ΅¬ν˜„ν•˜λŠ” 방법은 적어도 μ €μ—κ²ŒλŠ” thread일 κ²ƒμž…λ‹ˆλ‹€. 고전적인 λ°©λ²•μ΄μ§€λ§Œ λͺ¨λ“  언어와 ν”Œλž«νΌμ—μ„œ μ§€μ›ν•˜λŠ” λ°©μ‹μ˜ multitasking을 μ²˜λ¦¬ν•˜λŠ” λ°©λ²•μž…λ‹ˆλ‹€.

ν•˜μ§€λ§Œ multitasking을 κ΅¬ν˜„ν•˜λŠ” 방법은 threadλ₯Ό μ΄μš©ν•˜λŠ” κ²ƒλ§Œ μžˆλŠ”κ²ƒμ€ μ•„λ‹ˆκ³  λ‹€μ–‘ν•œ νŒ¨ν„΄μ„ ν™œμš©ν•˜μ—¬ κ΅¬ν˜„ν•  수 μžˆμŠ΅λ‹ˆλ‹€. multitasking에 κ΄€λ ¨λœ μš©μ–΄λ‚˜ 방법듀에 λŒ€ν•΄μ„œλŠ” μ €λŠ” κ²½ν—˜μ μœΌλ‘œ μ–»μ—ˆλ˜ 지식이라 μŠ€μŠ€λ‘œλ„ 정리가 잘 μ•ˆλ˜μ–΄μžˆμŠ΅λ‹ˆλ‹€. κ·Έλž˜μ„œ μ΄λ²ˆμ— κ°œλ…κ³Ό μš©μ–΄λ₯Ό ν”„λ‘œκ·Έλž˜λ° μ–Έμ–΄μ˜ λŸ°νƒ€μž„μ—μ„œλŠ” μ–΄λ–»κ²Œ κ΅¬ν˜„λ˜μ–΄ μžˆλŠ”μ§€λ„ μ•Œμ•„λ³΄λ €ν•©λ‹ˆλ‹€. 이 κΈ€μ˜ μ‹œλ¦¬μ¦ˆμ—μ„œλŠ” Concurrent vs Parallel, Preemptive vs Non-preemptive multitasking의 κ°œλ…μ— λŒ€ν•΄μ„œ μ•Œμ•„λ³΄κ³  μ΄μ–΄μ„œ Coroutine, Generator, Thread, Async/Await, Reactive의 κ°œλ…λ“€κ³Ό Pythonκ³Ό Go μ–Έμ–΄μ—μ„œλŠ” 각 κ°œλ…μ„ μ–΄λ–»κ²Œ λŸ°νƒ€μž„μ— κ΅¬ν˜„ν–ˆλŠ”μ§€ 컀널 λ ˆλ²¨μ—μ„œ λ™μž‘μ— λŒ€ν•΄μ„œ μ„€λͺ…ν•  μ˜ˆμ •μž…λ‹ˆλ‹€.

Concurrent와 Parallel의 λ™μ§ˆμ„±

μš°μ„  Concurrent의 μ˜μ˜μ‚¬μ „ λœ»μ„ ν™•μΈν•˜λ©΄ λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.

Concurrent

the fact of two or more events or circumstances happening or existing at the same time.

볡수의 μ‚¬κ±΄μ΄λ‚˜ 상황이 같은 μ‹œκ°„μ— λ²Œμ–΄μ§€κ±°λ‚˜ μ‘΄μž¬ν•˜λŠ” 것 μ΄λΌλŠ” 해석이 κ°€λŠ₯ν•©λ‹ˆλ‹€. 같은 μ‹œκ°„μ΄λΌλŠ” 말이 쑰금 μ• λ§€ν•˜μ§€λ§Œ μ•„λž˜ 예제λ₯Ό 생각해보면 이해가 μ‰½μŠ΅λ‹ˆλ‹€.

κ·Έ μ‚¬λžŒμ€ λ™μ‹œμ— μš”λ¦¬ 3개λ₯Ό ν•  수 μžˆλ‹€.

예λ₯Ό λ“€μ–΄ μš”λ¦¬λ₯Ό ν•˜λŠ”λ° νŒŒμŠ€νƒ€λ„ ν•˜κ³  μŠ€ν…Œμ΄ν¬λ„ κ΅¬μš°λ©΄μ„œ μΉ˜ν‚¨λ„ 같이 κ΅¬μ›Œ μ†λ‹˜μ—κ²Œ μ„œλΉ™ν•  수 μžˆλ‹€λ©΄ 이 μ‚¬λžŒμ€ λ™μ‹œμ„±μ„ κ°–λŠ” μš”λ¦¬μ‚¬λΌκ³  λ³Ό 수 μžˆμŠ΅λ‹ˆλ‹€.

λ™μ‹œλΌλŠ” 말은 μ• μ΄ˆμ— λ‹¨μ–΄μ˜ ν•œμž λœ»μ—μ„œ λ‚˜νƒ€λ‚˜ λ“― (concurrentλΌλŠ” μ˜μ–΄λ„ λ§ˆμ°¬κ°€μ§€λ‘œ) 같은 μ‹œκ°„μ— 볡수의 일을 μ²˜λ¦¬ν•˜λŠ” 경우 뢙일 수 μžˆμŠ΅λ‹ˆλ‹€. μœ„μ˜ λ¬Έμž₯을 CSμ—μ„œ μ‚¬μš©ν•˜λŠ” μš©μ–΄λ‘œ 살짝 λ°”κΎΈλ©΄.. μ•„λž˜μ™€ κ°™μŠ΅λ‹ˆλ‹€.

μ›Œμ»€ ν•˜λ‚˜κ°€ λ™μ‹œμ— μš”μ²­ 100개λ₯Ό μ²˜λ¦¬ν•œλ‹€.

ν•˜λ‚˜μ˜ μ›Œμ»€κ°€ λ™μ‹œμ— μš”μ²­μ„ 100개 μ²˜λ¦¬ν•˜λ©΄ λ™μ‹œμ„±μ„ κ°–λŠ” μ›Œμ»€λΌκ³  λ³Ό 수 μžˆμŠ΅λ‹ˆλ‹€. 일반적인 μžλ°” μ„œλ²„λ‘œ 보면 풀에 μ›Œμ»€ ν”„λ‘œμ„Έμ„œκ°€ μžˆμ„κ²ƒμ΄κ³  μ›Œμ»€λ§ˆλ‹€ μ‚¬μš©κ°€λŠ₯ν•œ μŠ€λ ˆλ“œ 풀이 λ”°λ‘œ μžˆκΈ°μ—, ν•˜λ‚˜μ˜ μ›Œμ»€λŠ” 항상 λ™μ‹œμ— 볡수의 μš”μ²­μ„ μ²˜λ¦¬ν•  수 μžˆμŠ΅λ‹ˆλ‹€. λ”°λΌμ„œ ν•˜λ‚˜μ˜ μ›Œμ»€λŠ” 항상 λ™μ‹œμ„±μ„ κ°–κ³  μžˆλ‹€ 말할 수 μžˆμŠ΅λ‹ˆλ‹€.

λ‹€μˆ˜μ˜ μž‘μ—…μ„ λ™μ‹œμ— μ²˜λ¦¬ν•˜λŠ” 것을 두가지 방법이 μžˆμŠ΅λ‹ˆλ‹€. μž‘μ—…μžκ°€ ν•΄μ•Όν•  일을 λ‚˜λˆ μ„œ λ™μ‹œμ— μž‘μ—…ν•˜λŠ” 방법이 있고 μ• μ΄ˆμ— 볡수의 μž‘μ—…μžκ°€ λ™μ‹œμ— μ²˜λ¦¬ν•˜λŠ” 방법이 μžˆμ„κ²ƒ μž…λ‹ˆλ‹€.

μ•„κΉŒ 예λ₯Ό λ“€μ—ˆλ˜ μš”λ¦¬μ˜ 예λ₯Ό λ“€μžλ©΄ ν•΄μ•Όν•˜λŠ” μš”λ¦¬λŠ” 총 3개라면 ν•œλͺ…μ˜ μš”λ¦¬μ‚¬κ°€ κ°€μŠ€λ Œμ§€κ°€ κ°–κ³  μžˆλŠ” κ°€μš©μ„±μ„ μΆ©λΆ„νžˆ λŒμ–΄λ‚΄μ„œ μŠ€ν…Œμ΄ν¬μ™€ νŒŒμŠ€νƒ€λ₯Ό μ μ ˆν•œ 타이밍을 λ§žμΆ°κ°€λ©΄μ„œ λ§Œλ“€μ–΄λ‚΄κ³  그와 λ™μ‹œμ— μ˜€λΈμ— μΉ˜ν‚¨λ„ κ΅½λŠ”λ‹€λ©΄ λ™μ‹œμ— 일을 λ™μ‹œμ— μ²˜λ¦¬ν–ˆλ‹€κ³  λ³Ό 수 μžˆμŠ΅λ‹ˆλ‹€. ν•˜μ§€λ§Œ 이런 방법 말고 3개의 μš”λ¦¬λ₯Ό μ• μ΄ˆμ— μ„œλ‘œ λ‹€λ₯Έ 3개의 μ£Όλ°©μ—μ„œ μ„œλ‘œ λ‹€λ₯Έ 3λͺ…μ˜ μš”λ¦¬μ‚¬κ°€ 각각 ν•œλͺ…μ”© μžμ‹ λ§Œμ˜ μš”λ¦¬λ₯Ό μ§„ν–‰ν•œλ‹€λ©΄? 이 λ˜ν•œ λ™μ‹œμ— μš”λ¦¬λ₯Ό λ§Œλ“€μ—ˆλ‹€κ³  λ³Ό 수 μžˆμŠ΅λ‹ˆλ‹€.

μœ„μ˜ μ˜ˆμ œμ—μ„œ ν›„μžλŠ” λ™μ‹œμ„±μ„ κ°–κΈ° μœ„ν•΄μ„œ λ³‘λ ¬μ μœΌλ‘œ 일을 μ²˜λ¦¬ν–ˆλ‹€κ³  λ³Ό 수 μžˆμŠ΅λ‹ˆλ‹€. 두 κ°œλ…μ„ λΉ„κ΅ν•˜λ©΄ λ™μ‹œμ„±μ€(concurrency)λŠ” ν•­μ‹œ λ‹€λ₯Έ μž‘μ—…μ„ μœ„ν•΄μ„œ 양보할 수 μžˆλŠ” μƒνƒœ(interruptability)λ₯Ό λ§ν•©λ‹ˆλ‹€. 병렬성(parallelism)은 λ‹€λ₯Έ μž‘μ—…λ“€μ΄ λͺ¨λ‘ λ…λ¦½μ μœΌλ‘œ 처리되고 μžˆλŠ” μƒνƒœ(independentability)λ₯Ό μΌμ»«μŠ΅λ‹ˆλ‹€.

마치 ν•œλͺ…μ˜ μš”λ¦¬μ‚¬κ°€ λ™μ‹œ μž‘μ—…μ„ ν•˜λ©΄ μŠ€ν…Œμ΄ν¬λ₯Ό 뒀집고 λ‚˜λ©΄ νŒŒμŠ€νƒ€λ₯Ό μ‚΄νŽ΄λ³΄λ©° μ†ŒμŠ€λ₯Ό λ„£μ–΄μ£Όκ³  κ·Έ λ‹€μŒμ—λŠ” 였븐의 μ˜ˆμ—΄μ΄ λλ‚œ μ•ŒλžŒμ„ λ“£κ³  μΉ˜ν‚¨μ„ μ˜€λΈμ— λ„£λŠ”κ²ƒ 같이 λ§μž…λ‹ˆλ‹€. ν•˜μ§€λ§Œ 병렬성을 κ°–λŠ” 방법인 ν›„μžμ˜ 방법은 λͺ¨λ“  μž‘μ—… 즉 μš”λ¦¬κ°€ 각자 독립성을 κ°–κ³  각각의 μš”λ¦¬μ‚¬κ°€ μš”λ¦¬ν•˜κ²Œ λ©λ‹ˆλ‹€.

이λ₯Ό CSμ—μ„œ 바라보면 λ‹€μˆ˜ ν”„λ‘œμ„Έμ„œ (multiprocessor, ν”ν•˜κ²ŒλŠ” λ©€ν‹° μ½”μ–΄)λ₯Ό μ΄μš©ν•΄μ„œ λ‹€μˆ˜μ˜ 일을 μ²˜λ¦¬ν•˜λ©΄ λ³‘λ ¬μ μœΌλ‘œ λ™μ‹œμ„± 있게 일을 μ²˜λ¦¬ν•˜λŠ” λ°©λ²•μž…λ‹ˆλ‹€. λ§Œμ•½ ν•˜λ‚˜μ˜ ν”„λ‘œμ„Έμ„œ(μ΄λŠ” μ‹±κΈ€μ½”μ–΄)μ—μ„œ λ‹€μˆ˜μ˜ 일을 μ²˜λ¦¬ν•œλ‹€λ©΄ μ΄λŠ” λ™μ‹œμ„±μ΄ μžˆλ‹€κ³  이야기할 μˆ˜λŠ” μžˆμ§€λ§Œ 각 μž‘μ—…μ΄ λ…λ¦½λ˜μ–΄μ„œ μ²˜λ¦¬λ˜μ§€λŠ” μ•ŠκΈ° λ•Œλ¬Έμ— 병렬적이라고 이야기할 수 μ—†μŠ΅λ‹ˆλ‹€.

그러면 λ³‘λ ¬μ μœΌλ‘œ 일을 μ²˜λ¦¬ν•˜λ©΄ 항상 λ™μ‹œμ„±μ„ κ°–μ„κΉŒμš”? κΌ­ κ·Έλ ‡μ§€λ§Œμ€ μ•ŠμŠ΅λ‹ˆλ‹€.

λ³‘λ ¬μ μ΄λ‚˜ λ™μ‹œμ μ΄μ§€ μ•Šμ„λ•Œ

λ³‘λ ¬λ‘œ 일을 μ²˜λ¦¬ν•΄λ„ 항상 λ™μ‹œμ μ΄μ§„ μ•ŠμŠ΅λ‹ˆλ‹€. μœ„μ˜ μš”λ¦¬μ˜ˆλ₯Ό λ‹€μ‹œ ν•œλ²ˆ 더 μΈμš©ν•˜λ©΄ 3λͺ…μ˜ μš”λ¦¬μ‚¬κ°€ μš”λ¦¬ν•˜λŠ”λ° λ§Œμ•½ κ°€μŠ€λ ˆμΈμ§€κ°€ ν•˜λ‚˜λΌλ©΄ (…) μ„œλ‘œ λ²ˆκ°ˆμ•„ κ°€λ©΄μ„œ μ‚¬μš©ν•˜λ©΄μ„œ μš”λ¦¬ν•΄μ•Όν•˜κΈ° λ•Œλ¬Έμ— λ™μ‹œμ„±μ„ κ°–κΈ° νž˜λ“­λ‹ˆλ‹€. μ΄λŠ” CSμ—μ„œλŠ” critical section이라고 μ΄μ•ΌκΈ°ν•©λ‹ˆλ‹€. 곡유 λ³€μˆ˜λ“±μ˜ 문제둜 μΈν•΄μ„œ λ³‘λ ¬μ μœΌλ‘œ 일은 μ²˜λ¦¬ν•˜μ§€λ§Œ λ‹€λ₯Έ 일이 μ²˜λ¦¬κ°€ λλ‚˜κΈ°λ₯Ό mutexλ₯Ό μ΄μš©ν•΄μ„œ 기닀리고 μ²˜λ¦¬λ˜μ•Όν•©λ‹ˆλ‹€. μ΄λŠ” λ³‘λ ¬μ μœΌλ‘œ 일을 μ²˜λ¦¬ν•˜κ³ λŠ” μžˆμœΌλ‚˜ λ™μ‹œμ— μ²˜λ¦¬λ˜λŠ”κ²ƒμ€ μ•„λ‹ˆκ²Œ λ©λ‹ˆλ‹€. λ”°λΌμ„œ λ™μ‹œμ„±κ³Ό 병렬성이 κΌ­ subset관계에 μžˆλ‹€κ³  λ³Ό μˆ˜λŠ” μ—†μŠ΅λ‹ˆλ‹€.