하나의 프로세스에서 도는 작업 들이며, 각각의 thread는 자신의 고유 stack 공간과, register 공간을 가짐.

여러 쓰레드가 하나의 프로세스에서 돌 수 있으며, 각각의 쓰레드는 동일한 데이터를 공유할 수 있음.

thread is light weight process

from threading import Thread

def func_simple(length):
		sum_f1 = 0
		for x in range(0, length):
				sum_f1 += x
		print(f"sum is {sum_f1}")

def func_square(length):
		sum_f2 = 0
		for x in range(0, length):
				sum_f2 += x * x
		print(f"square sum is {sum_f2}")

def func_cubes(length):
		sum_f3 = 0
		for x in range(0, length):
				sum_f3 += x * x * x
		print(f"cube sum is {sum_f3}")

def do_threading():
		length = 3
		thread_simple = Thread(target=func_simple, args=(length, ))
		thread_square = Thread(target=func_square, args=(length, ))
		thread_cubes = Thread(target=func_cubes, args=(length, ))

		thread_simple.start()
		thread_square.start()
		thread_cude.start()

		thread_simple.join()
		thread_square.join()
		thread_cude.join()

do_threading()

# "sum is 3" 0 + 1 + 2
# "square sum is 5" 0 + 1 + 4
# "cube sum 9 " 0 + 1 + 8

Using lock with Thread

여러개의 thread들이 동일한 데이터에 동시에 접근할 수 있고, 다른 thread가 데이터를 변경시키는 과정에 그 뒤에 오는 thread가 데이터를 사용하려면 문제가 발생 —> lock을 통해 해결

from threading import Thread, Lock

thread_lock = Lock()

my_global_string = "Hello World"

def add_prefix(prefix_to_add):
		
		global my_global_string
		with thread_lock:
				my_global_string = prefix_to_add + " " + my_global_string

def add_suffix(suffix_to_add):
		
		global my_global_string
		with thread_lock:
				my_global_string = my_global_string + " " + suffix_to_add

def do_threading():
		thread_prefix = Thread(target=add_prefix, args=('YOLO', ))
		thread_suffix = Thread(target=add_suffix, args=('BYE'))
		
		thread_prefix.start()
		thread_suffix.start()

		thread_prefix.join()
		thread_suffix.join()

		global my_global_string
		print(f"final_string is {my_global_string}")
		

do_threading()
# 'YOLO Hello World BYE'

Re-entrant Lock

하나의 공유 변수에 대한 acquire를 여러번 할 수 있음. [deadlock 을 막기 위해]

Lock vs Re-entrant Lock

from threading import RLock

lock = RLock()

def factorial(n):
    assert n > 0
    if n == 1:
        return 1
    
    with lock:       
        out = n * factorial(n - 1)

    return out

# Lock 이라면 deadlock 걸림.