Python_4 - jjin-choi/study_note GitHub Wiki

Β§ Parallel process

https://github.com/imguru-mooc/python_intermediate/tree/master/5.%EB%B3%91%EB%A0%AC%20%EC%B2%98%EB%A6%AC

1. Thread

  • from threading import Thread
    • Thread() λŠ” thread κ°€ μ‹€ν–‰ν•  λ™μž‘μ„ μ„€μ •ν•˜λŠ” μ½”λ“œμ΄λ©° start() μ‹œ thread κ°€ μˆ˜ν–‰
    • thread λ₯Ό μ’…λ£Œμ‹œν‚€κΈ° μœ„ν•΄μ„œλŠ” flag λ₯Ό 지정해주면 μ’‹λ‹€.
from threading import Thread
import time

class CountdownTask:
    def __init__(self):
        self._running = True

    def terminate(self):
        self._running = False

    def run(self, n):
        while self._running and n > 0:
            print("T-minus", n)
            n -= 1
            time.sleep(5)

c = CountdownTask()
t = Thread(target=c.run, args=(10,))
t.start()

time.sleep(20)
print('About to terminate')
c.terminate()
t.join()
print('Terminated')
  • Event() 객체 : thread κ°€ 잘 μ‹œμž‘λ˜μ—ˆλŠ”μ§€ ν™•μΈν•˜κ³  싢을 λ•Œ ν˜Ήμ€ thread κ°€ νŠΉμ • 지점에 λ„λ‹¬ν–ˆλŠ”μ§€ μ•Œμ•„μ•Ό ν•  경우
    • evt = Event() 라고 μƒμ„±ν•˜λ©΄, 생성과 λ™μ‹œμ— λ‚΄λΆ€ 값이 0 으둜 μ΄ˆκΈ°ν™” λœλ‹€.
    • ν•¨μˆ˜μ˜ args 둜 evt λ₯Ό μ£Όκ³  ν•¨μˆ˜ λ‚΄λΆ€μ—μ„œ evt.set() 을 ν•˜λ©΄ Event 값은 1 이 됨
    • λ³‘λ ¬μ²˜λ¦¬ ν•˜λŠ” λΆ€λΆ„μ—μ„œ evt.wait() λ₯Ό ν•˜λ©΄, 1 이 λ˜λŠ” μˆœκ°„ κ·Έ 뢀뢄도 κΈ°λ™λœλ‹€.
import time

def countdown(n, started_evt):
    print("countdown starting")
    started_evt.set() 
    while n > 0:
        print("T-minus", n)
        n -= 1
        time.sleep(5)

started_evt = Event()

print("Launching countdown")
t = Thread(target=countdown, args=(10,started_evt))
t.start()

started_evt.wait()
print("countdown is running")
  • ν•˜μ§€λ§Œ Event λŠ” ν•œ 번 μ“°κΈ°μ—λŠ” μ’‹μ§€λ§Œ, 주기적으둜 μ‚¬μš©ν•˜κΈ°μ—λŠ” 쒋지 μ•Šμ•„ β†’ Condition() 을 μ‚¬μš©ν•˜μž !
    • Condition 은 지속가λŠ₯ν•œ νŠΉμ„±μ΄ 있고 μžλ™μœΌλ‘œ locking λ˜λŠ” κΈ°λŠ₯이 μžˆλ‹€.
import threading
import time

class PeriodicTimer:
    def __init__(self, interval):
        self._interval = interval
        self._flag = 0
        self._cv = threading.Condition()

    def start(self):
        t = threading.Thread(target=self.run)
        t.daemon = True
        t.start()

    def run(self):
        while True:
            time.sleep(self._interval)
            with self._cv:
                 self._flag ^= 1
                 self._cv.notify_all()

    def wait_for_tick(self):
        with self._cv:
            last_flag = self._flag
            while last_flag == self._flag:
                self._cv.wait()

ptimer = PeriodicTimer(5)
ptimer.start()

def countdown(nticks):
    while nticks > 0:
        ptimer.wait_for_tick()
        print("T-minus", nticks)
        nticks -= 1

def countup(last):
    n = 0
    while n < last:
        ptimer.wait_for_tick()
        print("Counting", n)
        n += 1

threading.Thread(target=countdown, args=(10,)).start()
threading.Thread(target=countup, args=(5,)).start()