볞묞윌로 걎너뛰Ʞ

🀔 Chapter 6: 동시성

동시성은 둘 읎상의 윔드 조각읎 싀행될 때 동시에 싀행 쀑읞 것처럌 행동하는 것읎닀. 귞늬고 병렬성읎란 싀제로 동시에 싀행되는 것읎닀.
동시성을 얻윌렀멎 싀행 쀑에 윔드의 닀륞 부분윌로 싀행을 전환할 수 있는 환겜에서 윔드륌 구동핎알 한닀. 볎통은 파읎버(fiber)나 슀레드, 프로섞슀 등을 사용하여 동시성을 구현한닀.
병렬성을 얻윌렀멎 두 가지 음을 동시에 할 수 있는 하드웚얎가 필요하닀.

🥕 몚든 음에 동시성읎 있닀​

시슀템의 규몚가 얎느 정도륌 넘얎가멎 동시성을 고렀하지 않고 윔드륌 작성하Ʞ란 거의 불가능하닀. 동시성을 겉윌로 드러날 때도 있지만 띌읎람러늬 안에 묻혀 있는 겜우도 있닀. 여러분의 애플늬쌀읎션읎 싀제 섞상을 닀룚Ʞ 원한닀멎 동시성은 필수닀. 섞상은 비동Ʞ적읎Ʞ 때묞읎닀. 만앜 순찚적윌로 하나륌 끝낾 닀음에 닀음 음을 하는 식윌로 수행한닀멎, 시슀템은 거북읎처럌 느늬게 느껎질 것읎고 프로귞랚을 구동하는 하드웚얎의 성능도 최대로 활용하지 못할 것읎닀.

🍭 Topic 33. 시간적 결합 깚튞늬Ʞ​

소프튞웚얎 아킀텍처에서 시간읎띌는 잡멎은 자죌 묎시된닀. 우늬가 신겜쓰는 유음한 시간은 음정, 바로 출시까지 낚은 시간뿐읎닀. 하지만 여Ʞ서 읎알Ʞ할 것은 읎런 종류의 시간읎 아니닀. 시간에는 우늬가 신겜 썚알 할 잡멎읎 두 가지 있는데, 동시성(동시에 음얎나는 음듀)곌 순서(시간의 흐멄 속에서 음듀의 상대적읞 위치)ë‹€.

우늬는 볎통 프로귞래밍할 때 두 ìž¡ë©Ž 몚두 특별히 신겚 쓰지 않는닀. 메서드 A는 얞제나 메서드 B볎닀 뚌저 혞출핎알 한닀. 볎고서는 한 번에 였직 하나만 생성할 수 있닀. 버튌 큎늭을 처늬하렀멎 뚌저 화멎읎 갱신되얎알 한닀.

읎러한 ì ‘ê·Œ 방법은 귞닀지 유연하지 않고 현싀곌도 동떚얎젞 있닀.
우늬는 동시성을 확볎핎알 한닀. 시간읎나 순서에 의졎하는 시간적 결합을 끊는 방법을 생각핎 ë‚Žì•Œ 한닀. 귞렇게 핚윌로썚 유연성도 얻을 수 있고, 작업 흐멄 분석곌 아킀텍처, 섀계, 배포와 같은 개발의 여러 잡멎에서 시간곌 ꎀ렚된 의졎성도 핚께 쀄음 수 있닀. 결곌적윌로 분석하Ʞ 더 쉜고 응답속도도 더 빠륎며 더 안정적읞 시슀템을 만듀 수 있을 것읎닀.

🥕 동시성 찟Ʞ​

우늬는 동시에 음얎나도 되는 게 뭐고, 반드시 순서대로 음얎나알 하는 걎 ì–Žë–€ 것읞지 ì°Ÿì•„ë‚Žêžž 원한닀. "활동 닀읎얎귞랚" 같은 표Ʞ법을 사용핎서 작업 흐늄을 귞록하는 것읎 한 방법읎닀.

TIP 56. 작업 흐멄 분석윌로 동시성을 개선하띌.

활동 닀읎얎귞랚을 사용하멎 동시에 수행할 수도 있는데도 아직 동시에 하고 있지 않은 활동듀을 ì°Ÿì•„ë‚Žì„œ 병렬성을 극대화할 수 있닀.

🥕 동시 작업의 Ʞ회​

활동 닀읎얎귞랚은 동시에 작업할 수 있는 부분듀을 볎여 쀀닀. 하지만 진짜로 동시에 하는 것읎 좋은지는 알렀죌지 않는닀. 귞래서 섀계가 필요하닀.
우늬는 시간읎 걞늬지만, 우늬 윔드가 아닌 곳에서 시간읎 걞늬는 활동을 ì°Ÿê³  싶닀. 데읎터베읎슀륌 조회할 때나 왞부 서비슀에 접귌할 때, 사용자 입력을 Ʞ닀늎 때 같읎 우늬 프로귞랚읎 닀륞 작업읎 끝나Ʞ륌 Ʞ닀렀알 하는 상황 말읎닀. 읎런 순간읎 바로 CPU가 손가띜만 빚멎서 Ʞ닀늬는 대신 좀 더 생산적읞 음을 할 수 있는 Ʞ회닀.

🥕 병렬 작업의 Ʞ회​

컎퓚터 한 대에 있든 아니멎 연결된 여러 대에 있든 우늬에게 여러 개의 프로섞서가 있닀멎, 귞늬고 작업을 프로섞서듀에게 나누얎 쀄 수 있닀멎 전첎 소요 시간을 닚축할 수 있닀.
읎런 식윌로 나누Ʞ에 가장 읎상적읞 것은 비교적 독늜적읞 부분 작업듀읎닀. 닀륞 부분 작업을 Ʞ닀늎 필요 없읎 진행할 수 있윌멎 좋닀. 음반적읞 형태는 컀닀란 작업을 독늜적읞 부분듀로 쪌개서 별렬로 각각 처늬한 닀음, 결곌륌 합치는 것읎닀.

🥕 Ʞ회륌 ì°Ÿì•„ 낮는 것은 쉜닀​

여러분의 애플늬쌀읎션윌로 돌아가자. 동시 작업읎나 병렬 작업을 í•Žì„œ 읎득을 볌 수 있는 부분을 찟았닀. 읎제 얎렀욎 부분읎 낚았닀. 얎떻게 안전하게 구현할 수 있을까?

🍭 Topic 34. 공유 상태는 틀며 상태​

여러분읎 가장 좋아하는 레슀토랑에 방묞했닀. 메읞 요늬륌 몚두 뚹은 후 종업원에게 혹시 애플파읎가 ë‚šì•„ 있는지 묻는닀. 종업원은 얎꺠 넘얎륌 돌아볎더니 진영장에 한 조각읎 ë‚šì•„ 있는 것을 확읞하고는 귞렇닀고 대답한닀. 여러분은 죌묞을 마치고 안도의 한숚을 낎쉰닀.
한펾 레슀토랑의 반대쪜에서도 닀륞 고객읎 종업원에게 같은 질묞을 하고 있닀. 읎 종업원도 진엎장을 쳐닀볎고는 한 조각읎 있는 것을 확읞하고 죌묞을 받는닀. 두 고객 쀑 한 명은 싀망하게 될 것읎닀.

Tip 57. 공유 상태는 틀며 상태닀.

묞제는 상태가 공유된 것읎닀. 레슀토랑의 종업원듀은 서로륌 고렀하지 않고 진엎장만 확읞했닀.

🥕 비-원자적 갱신​

종업원1읎 현재 파읎 조각 수륌 조회하고, 1을 얻는닀. 귞러고는 고객에게 파읎륌 앜속한닀. 하지만 읎 시점에 종업원2도 작업을 시작한닀. 역시 파읎 조각 수륌 조회하여 1을 얻고, 고객에게 똑같은 앜속을 한닀. 둘 쀑 하나가 마지막 낚은 파읎 조각을 획득하고, 닀륞 종업원은 음종의 예왞 상태에 빠진닀.

여Ʞ서 묞제는 두 프로섞슀가 같은 메몚늬 영역을 ì“°êž°ê°€ 가능하닀는 점읎 아니닀. 묞제는 얎느 프로섞슀도 자신읎 볎는 메몚늬가 음ꎀ되얎 있음을 볎장할 수 없닀는 점읎닀. 읎것은 몚두 파읎 조각을 가젞였고 갱신하는 동안읎 원자적읎지 ì•Šêž° 떄묞읎닀. 싀제 값읎 귞사읎에 바뀔 수 있닀. 귞렇닀멎 얎떻게 원자적윌로 바꿀 수 있을까?

섞마포얎 및 닀륞 상혞 배제 방법​

섞마포얎는 닚순히 한 번에 한 사람만읎 가질 수 있는 묎얞가닀. 여러분은 섞마포얎륌 만듀얎서 닀륞 늬소슀의 사용을 제얎하는 데 ì“ž 수 있닀.

레슀토랑에서는 묌늬적읞 섞마포얎로 파읎 묞제륌 핎결하Ʞ로 했닀. 진엎장 위에 도깚비 읞형을 하나 올렀 둔닀. 몚든 종업원은 파읎 죌묞을 받Ʞ 전에 도깚비 읞형을 손에 넣얎알 한닀. 죌묞을 받고 파읎륌 접시에 ë‹Žì•„ 고객에게 낾 후에는 도깚비 읞형을 볎묌 파읎륌 지킀는 원래 위치에 되돌렀 놓는닀. 닀음 죌묞을 받을 수 있도록 말읎닀.

case_semaphore.lock()

if display_case.pie_count > 0
promise_pie_to_customer()
display_case.take_pie()
give_pie_to_customer()
end

case_semaphore.unlock()

두 종업원읎 동시에 윔드륌 싀행시쌰닀고 가정핎 볎자. 둘 ë‹€ 섞마포얎륌 얻윌렀고(lock) 시도하지만 한 명만 성공한닀. 섞마포얎륌 확볎한 쪜은 평소처럌 계속 진행한닀. 섞마포얎륌 얻지 못한 쪜은 섞마포얎륌 얻을 수 있을 때까지 멈춰 있는닀. 슉, Ʞ닀늰닀. 첫 번짞 종업원읎 죌묞을 완료하고 섞마포얎의 잠ꞈ을 핎제하멎 닀륞 종업원읎 싀행을 재개한닀.

읎 ì ‘ê·Œ 방식에는 몇 가지 묞제가 있닀. 가장 큰 묞제는 진영장에 접귌하는 몚든 사람읎 빠짐없읎 섞마포얎륌 사용핎알만 제대로 동작한닀는 것읎닀. 만앜 누군가가 깜빡한닀멎, 닀시 말핎서 ì–Žë–€ 개발자가 앜속을 지킀지 않는 윔드륌 쓎닀멎 닀시 혌돈에 빠진닀.

늬소슀륌 튞랜잭션윌로 ꎀ늬하띌​

현재의 섀계가 믞흡한 것은 진엎장 사용을 볎혞할 책임을 진엎장을 사용하는 사람에게 전가하Ʞ 때묞읎닀. 제얎륌 쀑앙윌로 집쀑시킀자. 귞러렀멎 API륌 바꿔서 종업원읎 하나의 혞출로 파읎 조각 수륌 확읞핚곌 동시에 파읎 조각을 가젞가도록 만듀얎알 한닀.

def get_pie_if_available()
@case_semaphore.protect() {
if @slices.size > 0
update_sales_data(:pie)
return @slices.shift
else
return false
end
}
end

🥕 튞랜잭션읎 없는 갱신​

공유 메몚늬는 동시성 묞제의 원읞윌로 많읎 지목받는닀. 하지만 사싀 수정 가능한 늬소슀륌 공유하는 애플늬쌀읎션 윔드 얎디에서나 동시성 묞제가 발생할 수 있닀. 여러분 윔드의 읞슀턎슀 둘 읎상읎 파음, 데읎터베읎슀, 왞부 서비슀 등 ì–Žë–€ 늬소슀에 동시에 접귌할 수 있닀멎 여러분은 잠재적읞 묞제륌 안고 있는 것읎닀.

Tip 58. 불규칙한 싀팚는 동시성 묞제읞 겜우가 많닀.

🥕 ê·ž 밖의 독점적읞 접귌​

대부분의 얞얎에는 공유 늬소슀에 독접적윌로 접귌하는 것을 도와죌는 띌읎람러늬가 있닀. 상혞 배제륌 의믞하는 뮀텍슀띌고 부륎Ʞ도 하고, 몚니터나 섞마포얎띌고 부륎Ʞ도 한닀. 몚두 띌읎람러늬로 제공된닀.

ì–žì–Ž 자첎에 동시성 지원읎 듀얎 있는 얞얎도 있닀. 예륌 듀얎 러슀튞는 데읎터의 소유권읎띌는 개념을 강제한닀. 변겜 가능한 데읎터 조각은 얎느 한 시점에 당 하나의 변수나 맀개 변수만 찞조륌 가질 수 있닀.

핚수형 얞얎듀은 몚든 데읎터륌 변겜 불가능하게 만드는 겜향읎 있윌므로 동시성 묞제륌 닚순하게 만든닀고 죌장할 수도 있겠닀. 하지만 핚수형 얞얎도 얞젠가는 몚든 것읎 변겜 가능한 진짜 섞상에 발을 듀여알 하므로 똑같은 묞제륌 겪는 순간읎 올 것읎닀.

🥕 의사 선생님, 아파요.....​

혹시 읎번 항목에서 얻얎 가는 것읎 없닀멎 읎것만은 Ʞ억하Ʞ륌 바란닀. 늬소슀륌 공유하는 환겜에서 동시성은 얎렵닀. 읎묞제륌 직접 풀렀고 한닀멎 고난의 연속음 것읎닀.

귞래서 닀음 였래된 농닎을 음믞핎볎Ʞ륌 추천하는 것읎닀.

의사 선생님, 읎렇게 하멎 아파요.
귞러멎 귞렇게 하지 마섞요.

🍭 Topic 35 액터와 프로섞슀​

액터와 프로섞슀륌 사용하멎 흥믞로욎 방식윌로 동시성을 구현할 수 있닀. 공유 메몚늬 접귌을 동Ʞ화하느띌 고생할 필요도 없닀.

  • 액터는 자신만의 비공개 지역 상태륌 가진 독늜적읞 가상 처늬 장치닀. 각 액터는 우펞핚을 하나씩 볎유하고 있닀. 액터가 잠자고 있을 때 우펞핚에 메시지가 도착하멎 액터가 깚얎나멎서 메시지륌 처늬한닀. 처늬가 끝나멎 우펞핚의 닀륞 메시지륌 처늬한닀. 만앜 우펞핚읎 비얎 있윌멎 닀시 ìž ë“ ë‹€. 메시지륌 처늬할 때 액터는 닀륞 액터륌 생성하거나, 알고 있는 닀륞 액터에게 메시지륌 볎낎거나, 닀음 메시지륌 처늬할 때의 상태가 될 새로욎 상태륌 생성할 수 있닀.
  • 프로섞슀는 볞래 더 음반적읞 가상 처늬Ʞ로, 볎통 욎영 첎제가 동시성을 지원하Ʞ 위하여 구현한닀. 프로섞슀륌 사용할 때 마치 액터처럌 동작하도록 ꎀ례륌 만듀얎 제한적윌로만 사용할 수도 있는데, 읎번 항목에서 읎알Ʞ하는 프로섞슀란 바로 읎렇게 제한한 것을 말한닀.

🥕 액터는 얞제나 동시성을 띀닀​

액터의 정의에서 찟아볌 수 없는 것읎 몇 가지 있닀.

  • 액터륌 ꎀ늬하는 것읎 하나도 없닀. 닀음에 묎엇을 하띌고 계획을 섞우거나, 정볎륌 입력 데읎터에서 최종 결곌로 바꟞는 곌정을 조윚하는 것읎 없닀.
  • 시슀템읎 지정하는 상태는 였직 메시지 귞늬고 각 액터의 지역 상태뿐읎닀. 메시지는 수신자가 읜는 것 왞에는 확읞할 방법읎 없고, 지역 상태는 액터 바깥에서는 접귌읎 불가능하닀.
  • 몚든 메시지는 음방향읎닀. 답장읎란 개념은 없닀. 액터에서 답장을 받고 싶닀멎 처음 메시지륌 볎낌 때 답장 받을 우펞핚 죌소륌 메시지에 포핚핎서 볎낎알 한닀. 나쀑에 읎 죌소로 볎낎는 답장도 ê²°êµ­ 또 하나의 메시지음 뿐읎닀.
  • 액터는 각 메시지륌 끝날 때까지 처늬하고 쀑간에 닀륞 음을 하지 않는닀. 슉, 한 번에 하나의 메시지만 처늬한닀.

ê·ž 결곌 액터듀은 아묎것도 공유하지 않윌멎서 비동Ʞ적윌로 동시에 싀행된닀. 묌늬적읞 프로섞서가 넉넉하닀멎 각각 액터륌 하나씩 돌멮 수 있닀. 프로섞서가 하나뿐읎띌멎 싀행 환겜읎 액터마닀 컚텍슀튞륌 전환핎 가멎서 싀행시킬 수 있닀. 얎느 쪜읎든 액터에서 싀행되는 윔드는 동음하닀.

Tip 59. 공유 상태 없는 동시성을 위하여 액터륌 사용하띌.

🥕 ê°„ë‹ší•œ 액터​

예시는 책을 ì°žê³ .

🥕 드러나지 않는 동시성​

액터 몚덞에서는 동시성을 닀룚는 윔드륌 ì“ž 필요가 없닀. 공유된 상태가 없Ʞ 때묞읎닀. 명시적윌로 처음부터 끝까지 "읎걞 한 닀음 저걞 하띌"는 윔드륌 ì“ž 필요도 없닀. 액터가 수신하는 메시지에 따띌 알아서 싀행되Ʞ 떄묞읎닀.

🍭 Topic 36. 칠판​

칠판 ì ‘ê·Œ 방법의 몇 가지 죌요 특징은 닀음곌 같닀.

  • 형사듀은 닀륞 형사의 졎재륌 알 필요가 없닀. 형사듀은 칠판을 볎며 새로욎 정볎륌 얻고, 자Ʞ가 발견한 것을 칠판에 덧붙읞닀.
  • 형사듀을 저마닀 서로 닀륞 분알의 훈렚을 받았거나, 닀륞 수쀀의 학력곌 겜험을 지녔을 수 있윌며, 아예 같은 ꎀ할 구역에 속하지 않을 수도 있닀. 사걎을 핎결하고 싶은 마음은 몚두에게 있지만, 공통점은 귞뿐읎닀.
  • 수사 곌정에서 여러 형사가 듀얎였거나 나갈 수 있고 임묎 교대 시간도 제각Ʞ 닀륌 수 있닀.
  • 칠판에는 제한 없읎 ì–Žë–€ 것읎든 올늎 수 있닀. 사진, 슝얞, 묌늬적 슝거 등등.

음종의 "자유방임죌의"적 동시성읎닀. 각 형사는 독늜된 프로섞슀, 에읎전튞, 액터 등곌 같닀. 누군가는 칠판에 수집한 사싀을 붙읎고, 누군가는 떌얎 ë‚žë‹€. 사싀을 조합하거나 처늬할 수도 있고 더 많은 정볎륌 덧붙음 수도 있닀. 칠판은 사람듀읎 서서히 결론에 도달하도록 돕는닀.

🥕 칠판 사용 사례​

죌택 닎볎 대출읎나 신용 대출 신청을 받아서 처늬하는 프로귞랚을 작성한닀고 가정핎 볎자. 읎 분알륌 ꎀ장하는 법은 정부, ꞈ융위원회, 지방 자치 닚첎 몚두 자신만의 규정읎 있Ʞ 때묞에 끔찍하게 복잡하닀. 대출 Ʞꎀ은 자신읎 몇몇 정볎륌 고지했닀는 사싀을 슝명핎알 하고, ì–Žë–€ 정볎륌 달띌고 요청핎알 하는데, ì–Žë–€ 질묞을 하멎 안 되는 등읎닀.
쀀수핎알 할 법읎띌는 곚칫거늬 왞에도 우늬가 씚늄핎알 할 묞제듀은 닀음곌 같닀.

  • 응답은 정핎진 순서 없읎 도착한닀. 예륌 듀얎 신용 조회나 명의 확읞 요청은 상당한 시간읎 걞늬지만, 읎늄읎나 죌소는 바로 확읞할 수 있닀.
  • 여러 표쀀 시간대에 걞쳐 있는 여러 사묎싀에 분산된 여러 사람읎 데읎터륌 수집할 수도 있닀.
  • ì–Žë–€ 데읎터 수집은 닀륞 시슀템읎 자동윌로 핎죌Ʞ도 한닀. 귞러나 읎 데읎터도 비동Ʞ적윌로 도착할 수 있닀는 점은 마찬가지닀.
  • 귞런 데닀가 ì–Žë–€ 데읎터는 닀륞 데읎터에 의졎하Ʞ까지 한닀.
  • 새로욎 데읎터가 도착하멎 새로욎 질묞을 하거나 새로욎 정책을 적용핎알 할 수도 있닀.

칠판 시슀템을 법적 요구 사항을 캡슐화하는 규칙 엔진곌 핚께 사용하멎 읎러한 얎렀움을 우아하게 í•Žê²°í•  수 있닀. 데읎터의 도착 순서는 읎제 상ꎀ 없닀. ì–Žë–€ 사싀읎 칠판에 올띌가멎 적절한 규칙읎 발동되도록 하멎 된닀. 결곌에 대한 플드백도 마찬가지로 쉜게 닀룰 수 있닀. ì–Žë–€ 규칙에서 나옚 것읎든 ê·ž 결곌륌 닀시 칠판에 올렀서 닀륞 규칙듀읎 발동되도록 하멎 된닀.

Tip 60. 칠판윌로 작업 흐늄을 조윚하띌.

🥕 메시지 시슀템곌 칠판의 유사성​

메시징 시슀템을 칠판윌로도 사용할 수 있고, 여러 액터륌 싀행하는 플랫폌윌로도 사용할 수 있닀는 것읎닀. 심지얎 동시에 둘 몚두륌 사용할 수도 있닀.

🥕 하지만 귞렇게 간닚하지 ì•Šë‹€...​

아킀텍처에서 액터와 칠판, 마읎크로서비슀륌 활용하멎 애플늬쌀읎션에서 생Ꞟ 수 있는 몚든 종류의 동시성 묞제륌 예방할 수 있을 것읎닀. 하지만 거Ʞ에는 비용읎 따륞닀. 읎런 ì ‘ê·Œ 방식을 사용하멎 많은 동작읎 간접적윌로 음얎나므로 분석읎 더 힘듀닀. 메시지 형식 및 API륌 몚아두는 쀑앙 저장소륌 욎영하멎 도움읎 될 것읎닀. 읎 저장소에서 윔드나 묞서까지 생성핎 쀀닀멎 더욱 좋닀. 시슀템에서 처늬하는 메시지나 정볎륌 추적할 수 있는 좋은 도구도 필요할 것읎닀. 유용한 Ʞ법을 하나 소개하겠닀.

특정한 비슈니슀 작업 처늬륌 시작할 때 고유한 "추적 아읎디"륌 만듀얎서 붙읎는 것읎닀. 귞늬고 핎당 작업에 ꎀ여하는 몚든 액터로 아읎디륌 전파하멎, 나쀑에 로귞 파음을 뒀젞서 ì–Žë–€ 음읎 음얎났는지 재구성핎 볌 수 있을 것읎닀.
마지막윌로 읎런 종류의 시슀템은 맞춰알 하는 구성 요소 수가 더 많Ʞ 때묞에 배포하고 ꎀ늬하Ʞ 더 까닀롭닀. 하지만 ê·ž 결곌 시슀템읎 더 잘게 쪌개지고, 전첎 시슀템읎 아니띌 개별 액터만 교첎하여 시슀템을 업데읎튞할 수 있닀는 멎에서 얎느 정도 볎상 받는닀.