CodeGym /ํ–‰๋™ /Python SELF KO /threading ๋ชจ๋“ˆ

threading ๋ชจ๋“ˆ

Python SELF KO
๋ ˆ๋ฒจ 25 , ๋ ˆ์Šจ 1
์‚ฌ์šฉ ๊ฐ€๋Šฅ

2.1 threading ๋ชจ๋“ˆ

Python์—์„œ์˜ ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋”ฉ์€ ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ (threads)๋ฅผ ๋™์‹œ์— ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์ด๋ฉฐ, ํŠนํžˆ ์ž…์ถœ๋ ฅ ์ž‘์—…์ด๋‚˜ ๋ณ‘๋ ฌ๋กœ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋Š” ์ž‘์—…์—์„œ CPU ์ž์›์„ ๋”์šฑ ํšจ์œจ์ ์œผ๋กœ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค˜.

Python์—์„œ ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋”ฉ์˜ ๊ธฐ๋ณธ ๊ฐœ๋…:

์Šค๋ ˆ๋“œ๋ž€ ์‹คํ–‰์˜ ์ตœ์†Œ ๋‹จ์œ„๋กœ, ํ•˜๋‚˜์˜ ํ”„๋กœ์„ธ์Šค ๋‚ด์—์„œ ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ์™€ ๋ณ‘๋ ฌ๋กœ ์ž‘๋™ํ•  ์ˆ˜ ์žˆ์–ด. ๋ชจ๋“  ์Šค๋ ˆ๋“œ๋Š” ํ•˜๋‚˜์˜ ํ”„๋กœ์„ธ์Šค ๋‚ด์— ์žˆ์–ด์„œ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๊ณต์œ ํ•˜๋ฉฐ, ์„œ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ๊ตํ™˜ํ•  ์ˆ˜ ์žˆ์ง€.

ํ”„๋กœ์„ธ์Šค๋ž€ ์šด์˜ ์ฒด์ œ์—์„œ ๊ณ ์œ ํ•œ ์ฃผ์†Œ ๊ณต๊ฐ„๊ณผ ์ž์›์„ ๊ฐ€์ง€๊ณ  ์‹คํ–‰๋˜๋Š” ํ”„๋กœ๊ทธ๋žจ์˜ ์ธ์Šคํ„ด์Šค์•ผ. ์Šค๋ ˆ๋“œ์™€ ๋‹ค๋ฅด๊ฒŒ, ํ”„๋กœ์„ธ์Šค๋ผ๋ฆฌ๋Š” ์„œ๋กœ ๊ฒฉ๋ฆฌ๋˜์–ด ์žˆ๊ณ , ๋ฐ์ดํ„ฐ๋Š” IPC(Inter-Process Communication)๋ฅผ ํ†ตํ•ด ๊ตํ™˜ํ•ด.

GIL์€ Python ์ธํ„ฐํ”„๋ฆฌํ„ฐ์˜ ๋ฉ”์ปค๋‹ˆ์ฆ˜์œผ๋กœ, ์—ฌ๋Ÿฌ Python ์Šค๋ ˆ๋“œ๊ฐ€ ๋™์‹œ์— ์‹คํ–‰๋˜๋Š” ๊ฒƒ์„ ๋ง‰์•„. GIL์€ Python ์ฝ”๋“œ์˜ ์•ˆ์ „ํ•œ ์‹คํ–‰์„ ๋ณด์žฅํ•˜์ง€๋งŒ, ๋ฉ€ํ‹ฐ์ฝ”์–ด ํ”„๋กœ์„ธ์„œ์—์„œ ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ ํ”„๋กœ๊ทธ๋žจ์˜ ์„ฑ๋Šฅ์„ ์ œํ•œํ•ด.

์ค‘์š”! Global Interpreter Lock (GIL) ๋•Œ๋ฌธ์—, ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋”ฉ์ด ๊ณ„์‚ฐ ์ง‘์ค‘ํ˜• ์ž‘์—…์— ๋Œ€ํ•ด ์„ฑ๋Šฅ ํ–ฅ์ƒ์„ ํฌ๊ฒŒ ๋ณด์žฅํ•˜์ง€ ๋ชปํ•  ์ˆ˜๋„ ์žˆ๋Š” ์ ์„ ๊ณ ๋ คํ•ด์•ผ ํ•ด. GIL์ด ๋ฉ€ํ‹ฐ์ฝ”์–ด ํ”„๋กœ์„ธ์„œ์—์„œ ์—ฌ๋Ÿฌ Python ์Šค๋ ˆ๋“œ์˜ ๋™์‹œ ์‹คํ–‰์„ ๋ง‰๊ธฐ ๋•Œ๋ฌธ์ด์•ผ.

threading ๋ชจ๋“ˆ

Python์˜ threading ๋ชจ๋“ˆ์€ ์Šค๋ ˆ๋“œ์™€ ์ž‘์—…ํ•˜๊ธฐ ์œ„ํ•œ ๊ณ ๊ธ‰ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ œ๊ณตํ•ด. ์Šค๋ ˆ๋“œ๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ๊ด€๋ฆฌํ•˜๋ฉฐ, ์ด๋“ค์„ ๋™๊ธฐํ™”ํ•˜๊ณ  ์ƒํ˜ธ์ž‘์šฉ์„ ์กฐ์งํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค˜. ์ด ๋ชจ๋“ˆ์˜ ์ฃผ์š” ๊ตฌ์„ฑ ์š”์†Œ์™€ ๊ธฐ๋Šฅ์„ ์ข€ ๋” ์ž์„ธํžˆ ์‚ดํŽด๋ณด์ž.

threading ๋ชจ๋“ˆ์˜ ์ฃผ์š” ๊ตฌ์„ฑ ์š”์†Œ

์Šค๋ ˆ๋“œ ์ž‘์—…์„ ์œ„ํ•œ ์—”ํ‹ฐํ‹ฐ:

  • Thread โ€” ์Šค๋ ˆ๋“œ ์ƒ์„ฑ ๋ฐ ๊ด€๋ฆฌ์˜ ๊ธฐ๋ณธ ํด๋ž˜์Šค.
  • Timer โ€” ์ง€์ •๋œ ์‹œ๊ฐ„์ด ์ง€๋‚˜๋ฉด ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰ํ•˜๋Š” ํƒ€์ด๋จธ.
  • ThreadLocal โ€” ์Šค๋ ˆ๋“œ์— ๋กœ์ปฌ ๋ฐ์ดํ„ฐ๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด.

์Šค๋ ˆ๋“œ ๋™๊ธฐํ™” ๋ฉ”์ปค๋‹ˆ์ฆ˜:

  • Lock โ€” ๊ณต์šฉ ์ž์›์— ๋Œ€ํ•œ ๋™์‹œ ์ ‘๊ทผ์„ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•œ ๋™๊ธฐํ™” ํ”„๋ฆฌ๋ฏธํ‹ฐ๋ธŒ.
  • Condition โ€” ๋ณด๋‹ค ๋ณต์žกํ•œ ์Šค๋ ˆ๋“œ ๋™๊ธฐํ™”๋ฅผ ์œ„ํ•œ ์กฐ๊ฑด ๋ณ€์ˆ˜.
  • Event โ€” ์Šค๋ ˆ๋“œ ๊ฐ„์˜ ์•Œ๋ฆผ์„ ์œ„ํ•œ ํ”„๋ฆฌ๋ฏธํ‹ฐ๋ธŒ.
  • Semaphore โ€” ํŠน์ • ๊ตฌ์—ญ์„ ๋™์‹œ์— ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋Š” ์Šค๋ ˆ๋“œ ์ˆ˜๋ฅผ ์ œํ•œํ•˜๋Š” ํ”„๋ฆฌ๋ฏธํ‹ฐ๋ธŒ.
  • Barrier โ€” ์„ค์ •๋œ ์ˆ˜์˜ ์Šค๋ ˆ๋“œ๋ฅผ ๋™๊ธฐํ™”ํ•˜์—ฌ, ๋ชจ๋“  ์Šค๋ ˆ๋“œ๊ฐ€ ๋„๋‹ฌํ•  ๋•Œ๊นŒ์ง€ ์ฐจ๋‹จํ•จ.

์•„๋ž˜์—์„œ ์Šค๋ ˆ๋“œ์™€ ์ž‘์—…ํ•  ์ˆ˜ ์žˆ๋Š” 3๊ฐ€์ง€ ํด๋ž˜์Šค๋ฅผ ์„ค๋ช…ํ•  ๊ฑฐ์•ผ. ๋™๊ธฐํ™” ๋ฉ”์ปค๋‹ˆ์ฆ˜์€ ๋‹น๋ถ„๊ฐ„ ํ•„์š” ์—†์„ ๊ฑฐ์•ผ.

2.2 Thread ํด๋ž˜์Šค

Thread ํด๋ž˜์Šค๋Š” ์Šค๋ ˆ๋“œ ์ƒ์„ฑ ๋ฐ ๊ด€๋ฆฌ์˜ ๊ธฐ๋ณธ ํด๋ž˜์Šค์•ผ. ์ด ํด๋ž˜์Šค์—๋Š” 4๊ฐ€์ง€ ์ฃผ์š” ๋ฉ”์„œ๋“œ๊ฐ€ ์žˆ์–ด:

  • start(): ์Šค๋ ˆ๋“œ ์‹คํ–‰์„ ์‹œ์ž‘ํ•ด.
  • join(): ํ˜„์žฌ ์Šค๋ ˆ๋“œ๊ฐ€ ๋Œ€๊ธฐํ•˜๊ณ , ์‹คํ–‰๋œ ์Šค๋ ˆ๋“œ๊ฐ€ ์™„๋ฃŒ๋  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ ค.
  • is_alive(): ์Šค๋ ˆ๋“œ๊ฐ€ ์‹คํ–‰ ์ค‘์ด๋ผ๋ฉด True๋ฅผ ๋ฐ˜ํ™˜ํ•ด.
  • run(): ์Šค๋ ˆ๋“œ์—์„œ ์‹คํ–‰ํ•  ์ฝ”๋“œ๋ฅผ ํฌํ•จํ•œ ๋ฉ”์„œ๋“œ. Thread ํด๋ž˜์Šค๋ฅผ ์ƒ์†๋ฐ›์•„ ์žฌ์ •์˜ํ•  ์ˆ˜ ์žˆ์–ด.

ํ›จ์”ฌ ๋” ๊ฐ„๋‹จํ•ด ๋ณด์ด๋Š” Thread ํด๋ž˜์Šค์˜ ์‚ฌ์šฉ ์˜ˆ์ œ.

๊ฐ„๋‹จํ•œ ์Šค๋ ˆ๋“œ ์‹œ์ž‘


import threading

def worker():
    print("Worker thread is running")
            
# ์ƒˆ ์Šค๋ ˆ๋“œ ์ƒ์„ฑ
t = threading.Thread(target=worker) #์ƒˆ ์Šค๋ ˆ๋“œ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ–ˆ์–ด
t.start() # ์Šค๋ ˆ๋“œ ์‹œ์ž‘
t.join() # ์Šค๋ ˆ๋“œ ์™„๋ฃŒ ๋Œ€๊ธฐ
print("Main thread is finished")
        

start ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•œ ํ›„, ํ•จ์ˆ˜ worker๊ฐ€ ์‹คํ–‰๋  ๊ฑฐ์•ผ. ์ข€ ๋” ์ •ํ™•ํžˆ ๋งํ•˜๋ฉด, ์Šค๋ ˆ๋“œ๊ฐ€ ํ™œ์„ฑ ์Šค๋ ˆ๋“œ ๋ชฉ๋ก์— ์ถ”๊ฐ€๋  ๊ฑฐ์•ผ.

์ธ์ˆ˜ ์‚ฌ์šฉ


import threading

def worker(number, text):
    print(f"Worker {number}: {text}")
            
# ์ธ์ˆ˜๊ฐ€ ์žˆ๋Š” ์ƒˆ ์Šค๋ ˆ๋“œ ์ƒ์„ฑ
t = threading.Thread(target=worker, args=(1, "Hello"))
t.start()
t.join()
        

์ƒˆ ์Šค๋ ˆ๋“œ์— ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์ „๋‹ฌํ•˜๋ ค๋ฉด, ๋‹จ์ˆœํžˆ ํŠœํ”Œ ํ˜•ํƒœ๋กœ args ๋งค๊ฐœ๋ณ€์ˆ˜์— ์ง€์ •ํ•ด ์ค„ ํ•„์š”๊ฐ€ ์žˆ์–ด. target์— ์ง€์ •๋œ ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋  ๋•Œ, ๋งค๊ฐœ๋ณ€์ˆ˜๋Š” ์ž๋™์œผ๋กœ ์ „๋‹ฌ๋  ๊ฑฐ์•ผ.

๋ฉ”์„œ๋“œ run ์žฌ์ •์˜


import threading

class MyThread(threading.Thread):
    def run(self):
        print("Custom thread is running")
            
# ์Šค๋ ˆ๋“œ ์ƒ์„ฑ ๋ฐ ์‹œ์ž‘
t = MyThread()
t.start()
t.join()
        

์ƒˆ๋กœ์šด ์Šค๋ ˆ๋“œ๋ฅผ ์‹œ์ž‘ํ•  ํ•จ์ˆ˜๋Š” ๋‘ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์œผ๋กœ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์–ด โ€” Thread ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•  ๋•Œ target ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ํ†ตํ•ด ์ „๋‹ฌํ•˜๊ฑฐ๋‚˜, Thread ํด๋ž˜์Šค๋ฅผ ์ƒ์†๋ฐ›์•„ run ํ•จ์ˆ˜๋ฅผ ์žฌ์ •์˜ํ•˜๋Š” ๊ฑฐ์•ผ. ๋‘ ๊ฐ€์ง€ ๋ฐฉ๋ฒ• ๋ชจ๋‘ ํ•ฉ๋ฒ•์ ์ด๊ณ  ์ž์ฃผ ์‚ฌ์šฉ๋ผ.

2.3 Timer ํด๋ž˜์Šค

threading ๋ชจ๋“ˆ์˜ Timer ํด๋ž˜์Šค๋Š” ์ง€์ •๋œ ์‹œ๊ฐ„ ํ›„์— ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰ํ•˜๊ธฐ ์œ„ํ•œ ๋ชฉ์ ์ด์•ผ. ์ด ํด๋ž˜์Šค๋Š” ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋”ฉ ํ™˜๊ฒฝ์—์„œ ์ง€์—ฐ๋œ ์ž‘์—…์„ ์‹คํ–‰ํ•˜๋Š” ๋ฐ ์œ ์šฉํ•˜์ง€.

ํƒ€์ด๋จธ๋Š” ํ˜ธ์ถœํ•  ํ•จ์ˆ˜์™€ ์ดˆ ๋‹จ์œ„์˜ ์ง€์—ฐ ์‹œ๊ฐ„์œผ๋กœ ์ƒ์„ฑ ๋ฐ ์ดˆ๊ธฐํ™”๋ผ.

  • ๋ฉ”์„œ๋“œ start()๋Š” ํƒ€์ด๋จธ๋ฅผ ์‹œ์ž‘ํ•˜๊ณ , ์ง€์ •๋œ ์‹œ๊ฐ„์ด ์ง€๋‚˜๋ฉด ์ฃผ์–ด์ง„ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•ด.
  • ๋ฉ”์„œ๋“œ cancel()์€ ํƒ€์ด๋จธ๊ฐ€ ์•„์ง ์‹คํ–‰๋˜์ง€ ์•Š์•˜์„ ๋•Œ ํƒ€์ด๋จธ๋ฅผ ๋ฉˆ์ถœ ์ˆ˜ ์žˆ์–ด. ํƒ€์ด๋จธ๊ฐ€ ๋” ์ด์ƒ ํ•„์š”ํ•˜์ง€ ์•Š์€ ๊ฒฝ์šฐ์— ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰ํ•˜์ง€ ์•Š๋„๋ก ๋ฐฉ์ง€ํ•˜๋Š”๋ฐ ์œ ์šฉํ•˜์ง€.

์‚ฌ์šฉ ์˜ˆ์ œ:

์ง€์—ฐ ์‹คํ–‰ ํ•จ์ˆ˜

์ด ์˜ˆ์ œ์—์„œ๋Š” ํƒ€์ด๋จธ๊ฐ€ ์‹œ์ž‘๋œ ํ›„ 5์ดˆ ๋’ค์— hello ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋˜์–ด.


import threading

def hello():
    print("Hello, world!")
            
# 5์ดˆ ๋’ค์— hello ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•  ํƒ€์ด๋จธ ์ƒ์„ฑ
t = threading.Timer(5.0, hello)
t.start()  # ํƒ€์ด๋จธ ์‹œ์ž‘
        

์‹คํ–‰ ์ „์— ํƒ€์ด๋จธ ๋ฉˆ์ถ”๊ธฐ

์—ฌ๊ธฐ์„œ๋Š” hello ํ•จ์ˆ˜๊ฐ€ ์‹คํ–‰๋˜๊ธฐ ์ „์— ํƒ€์ด๋จธ๊ฐ€ ๋ฉˆ์ถ”๊ธฐ ๋•Œ๋ฌธ์— ์•„๋ฌด๊ฒƒ๋„ ์ถœ๋ ฅ๋˜์ง€ ์•Š์•„.


import threading

def hello():
    print("Hello, world!")
            
# ํƒ€์ด๋จธ ์ƒ์„ฑ
t = threading.Timer(5.0, hello)
t.start()  # ํƒ€์ด๋จธ ์‹œ์ž‘
            
# ์‹คํ–‰ ์ „์— ํƒ€์ด๋จธ ๋ฉˆ์ถ”๊ธฐ
t.cancel()
        

์ธ์ˆ˜ ์žˆ๋Š” ํƒ€์ด๋จธ

์ด ์˜ˆ์ œ์—์„œ๋Š” ํƒ€์ด๋จธ๊ฐ€ 3์ดˆ ํ›„์— greet ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๊ณ  ์ธ์ˆ˜ "Alice"๋ฅผ ์ „๋‹ฌํ•ด.


import threading

def greet(name):
    print(f"Hello, {name}!")
            
# ์ธ์ˆ˜ ์žˆ๋Š” ํƒ€์ด๋จธ ์ƒ์„ฑ
t = threading.Timer(3.0, greet, args=["Alice"])
t.start()
        

Timer ํด๋ž˜์Šค๋Š” ์ผ์ • ์‹œ๊ฐ„ ํ›„์— ์ž‘์—…์„ ๊ณ„ํšํ•˜๋Š” ๋ฐ ํŽธ๋ฆฌํ•ด. ๋‹ค๋งŒ ํƒ€์ด๋จธ๋Š” ์ž‘์—… ์‹คํ–‰์˜ ์ ˆ๋Œ€์ ์ธ ์ •ํ™•์„ฑ์„ ๋ณด์žฅํ•˜์ง€๋Š” ์•Š์Œ, ์‹œ์Šคํ…œ ๋ถ€ํ•˜์™€ ์Šค๋ ˆ๋“œ ์Šค์ผ€์ค„๋Ÿฌ ์ž‘๋™์— ๋”ฐ๋ผ ๋‹ค๋ฅด์ง€.

2.4 ThreadLocal ํด๋ž˜์Šค

ThreadLocal ํด๋ž˜์Šค๋Š” ๊ฐ ์Šค๋ ˆ๋“œ๋งˆ๋‹ค ๊ณ ์œ ํ•œ ๋กœ์ปฌ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ง€๋„๋ก ํ•˜๊ธฐ ์œ„ํ•œ ํด๋ž˜์Šค๋กœ, ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ๊ฐ ์Šค๋ ˆ๋“œ๊ฐ€ ์ถฉ๋Œ ์—†์ด ์ž์‹ ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์•ผ ํ•  ๋•Œ ์œ ์šฉํ•ด.

ThreadLocal์„ ์‚ฌ์šฉํ•˜๋Š” ๋ชจ๋“  ์Šค๋ ˆ๋“œ์—๋Š” ์ž์‹ ๋งŒ์˜ ๊ณ ์œ ํ•œ ๋ฐ์ดํ„ฐ ์‚ฌ๋ณธ์ด ์žˆ์–ด. ThreadLocal ๊ฐ์ฒด์— ์ €์žฅ๋œ ๋ฐ์ดํ„ฐ๋Š” ๊ฐ ์Šค๋ ˆ๋“œ๋งˆ๋‹ค ๋…๋ฆฝ์ ์ด๊ณ  ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ์™€ ๊ณต์œ ๋˜์ง€ ์•Š์•„. ํ˜„์žฌ ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์‚ฌ์šฉ์ž๋‚˜ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์™€์˜ ํ˜„์žฌ ์—ฐ๊ฒฐ ๋“ฑ ํŠน์ • ์Šค๋ ˆ๋“œ ๋‚ด์—์„œ๋งŒ ์‚ฌ์šฉํ•˜๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•˜๊ธฐ์— ์ข‹์ง€.

์‚ฌ์šฉ ์˜ˆ์ œ:

๊ธฐ๋ณธ ์‚ฌ์šฉ

์ด ์˜ˆ์ œ์—์„œ๋Š” ๊ฐ ์Šค๋ ˆ๋“œ๊ฐ€ ๋กœ์ปฌ ๋ณ€์ˆ˜ value์— ์ž์‹ ์˜ ์ด๋ฆ„์„ ํ• ๋‹นํ•˜๊ณ  ์ถœ๋ ฅํ•ด. value์˜ ๊ฐ’์€ ๊ฐ ์Šค๋ ˆ๋“œ๋งˆ๋‹ค ์œ ์ผํ•ด.


import threading

# ThreadLocal ๊ฐ์ฒด ์ƒ์„ฑ
local_data = threading.local()
            
def process_data():
    # ์Šค๋ ˆ๋“œ ๋กœ์ปฌ ๋ณ€์ˆ˜์— ๊ฐ’ ํ• ๋‹น
    local_data.value = threading.current_thread().name
    # ์Šค๋ ˆ๋“œ ๋กœ์ปฌ ๋ณ€์ˆ˜์— ์ ‘๊ทผ
    print(f'Value in {threading.current_thread().name}: {local_data.value}')

threads = []
for i in range(5):
    t = threading.Thread(target=process_data)
    threads.append(t)
    t.start()

for t in threads:
    t.join()

์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ์‚ฌ์šฉ์ž ๋ฐ์ดํ„ฐ ์ €์žฅ

์ด ์˜ˆ์ œ์—์„œ๋Š” ๊ฐ ์Šค๋ ˆ๋“œ๊ฐ€ ์‚ฌ์šฉ์ž ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•ด. user_data.user ๊ฐ’์€ ๊ฐ ์Šค๋ ˆ๋“œ๋งˆ๋‹ค ์œ ์ผํ•ด.


import threading
# ThreadLocal ๊ฐ์ฒด ์ƒ์„ฑ
user_data = threading.local()
def process_request(user):
    # ์Šค๋ ˆ๋“œ ๋กœ์ปฌ ๋ณ€์ˆ˜์— ๊ฐ’ ํ• ๋‹น
    user_data.user = user
    handle_request()

def handle_request():
    # ์Šค๋ ˆ๋“œ ๋กœ์ปฌ ๋ณ€์ˆ˜์— ์ ‘๊ทผ
    print(f'Handling request for user: {user_data.user}')

threads = []
users = ['Alice', 'Bob', 'Charlie']
for user in users:
    t = threading.Thread(target=process_request, args=(user,))
    threads.append(t)
    t.start()

for t in threads:
    t.join()

์ด๊ฒŒ threading ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—์„œ ๊ฐ€์žฅ ์œ ์šฉํ•œ 3๊ฐ€์ง€ ํด๋ž˜์Šค์˜€์–ด. ์•„๋งˆ๋„ ์ด ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์ž‘์—…ํ•  ๊ฐ€๋Šฅ์„ฑ์ด ํฌ์ง€๋งŒ, ๋‚˜๋จธ์ง€ ํด๋ž˜์Šค๋Š” ์•„๋งˆ๋„ ๊ฑฐ์˜ ์‚ฌ์šฉํ•  ์ผ์ด ์—†์„ ๊ฑฐ์•ผ. ์š”์ฆ˜ ๋ชจ๋‘๊ฐ€ ๋น„๋™๊ธฐ ํ•จ์ˆ˜์™€ asyncio ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋กœ ์ „ํ™˜ํ•˜๊ณ  ์žˆ์–ด. ์•ž์œผ๋กœ๋Š” ์ด asyncio ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์— ๋Œ€ํ•ด ๊ณ„์† ์ด์•ผ๊ธฐํ•  ๊ฑฐ์•ผ.

์ฝ”๋ฉ˜ํŠธ
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION