[Python]스레드(Threads)

nongnola·2024년 7월 2일

Python

목록 보기
11/17

스레드란?

스레드는 프로그램의 실행 단위입니다. 쉽게 말해, 하나의 프로그램이 여러 작업을 동시에 처리하기 위해 나누어지는 작은 작업 단위라고 할 수 있습니다. 스레드는 일반적으로 동일한 메모리 공간을 공유하기 때문에 서로 간의 데이터 접근이 빠르지만, 그로 인해 발생할 수 있는 충돌 문제도 있습니다.

예를 들어, 당신이 인터넷 브라우저를 사용하고 있다고 가정해봅시다. 한 스레드는 웹페이지를 불러오고, 다른 스레드는 불러온 웹페이지를 화면에 표시합니다. 이러한 방식으로 스레드는 프로그램의 효율성을 높여줍니다.


프로세스란?

프로세스는 실행 중인 프로그램을 의미합니다. 각 프로세스는 독립된 메모리 공간을 가지며, 여러 개의 스레드를 포함할 수 있습니다. 프로세스 간에는 메모리 공간이 격리되어 있어 서로 간섭할 수 없습니다. 이는 시스템의 안정성을 높여줍니다.

예를 들어, 당신이 워드 프로세서와 음악 재생 프로그램을 동시에 실행하고 있다면, 각 프로그램은 독립적인 프로세스로 실행됩니다. 이 때문에 한 프로그램이 충돌해도 다른 프로그램은 영향을 받지 않습니다.


메인 스레드와 메세지 큐

메인 스레드는 프로그램이 실행될 때 가장 먼저 시작되는 기본 스레드입니다. 메인 스레드는 보통 UI를 관리하고 사용자 입력을 처리합니다. 메인 스레드가 바쁘면 프로그램이 응답하지 않게 되는 경우가 많습니다.

메세지 큐는 메인 스레드가 처리해야 할 작업들을 저장하는 구조입니다. 예를 들어, 사용자가 버튼을 클릭하면 그 이벤트가 메세지 큐에 저장되고, 메인 스레드는 이 메세지를 꺼내와서 처리합니다. 메세지 큐는 작업들이 순차적으로 처리되도록 보장해줍니다.

import threading
import queue

def worker():
    while True:
        item = q.get()
        if item is None:
            break
        print(f'Processing item: {item}')
        q.task_done()

q = queue.Queue()
threads = []
for i in range(5):
    t = threading.Thread(target=worker)
    t.start()
    threads.append(t)

for item in range(10):
    q.put(item)

q.join()

for i in range(5):
    q.put(None)
for t in threads:
    t.join()

위 코드에서 메세지 큐 q를 사용하여 작업들을 스레드들에게 분배하고 처리합니다.


멀티 스레드란?

멀티 스레드는 하나의 프로그램 내에서 여러 스레드가 동시에 작업을 수행하는 것을 의미합니다. 이는 프로그램의 효율성을 높여주지만, 스레드 간의 자원 공유 문제를 신경 써야 합니다.

예를 들어, 다운로드 매니저 프로그램을 생각해봅시다. 이 프로그램은 여러 파일을 동시에 다운로드하기 위해 각 파일 다운로드 작업을 별도의 스레드로 나눕니다. 이로 인해 다운로드 속도가 향상됩니다.

하지만 멀티 스레드를 사용할 때 주의해야 할 점은 스레드 간의 동기화 문제입니다. 여러 스레드가 동시에 공유 자원에 접근하면 데이터 손상이 발생할 수 있습니다. 이를 방지하기 위해 Lock 같은 동기화 기법을 사용합니다.

import threading

counter = 0
lock = threading.Lock()

def increment():
    global counter
    for _ in range(10000):
        with lock:
            counter += 1

threads = []
for _ in range(10):
    t = threading.Thread(target=increment)
    t.start()
    threads.append(t)

for t in threads:
    t.join()

print(f'Final counter value: {counter}')

위 예제에서 lock을 사용하여 스레드 간의 자원 접근을 동기화합니다. 이를 통해 데이터 손상을 방지할 수 있습니다.

0개의 댓글