thread

Thread

Light Weight Process 라고도 하며, 작은 프로세스라고 생각하면 된다.
스레드는 하나의 프로세스 안에서 여러개 생성이 가능하기 때문에 IPC 이를 이요하지 않더라도 각 스래드 끼리 데이터를 통신할 수 있다.

스레드는 프로세스에서 스택과 힙 사이 영역에 각각의 스레드를 위한 공간을 할당하는 방식을 동작한다.
각각의 영역 안에서 PC와 SP 를 가지기 때문에 독립적으로 동작할 수 있으면서도 프로세스에 나머지 영역을 공유 하기 때문에 데이터를 다른 스레드의 결과로 생긴 데이터라도 참조 할 수 있다.


멀티 프로세싱과 Thread

  • 멀티 태스킹 : 하나의 CPU에 여러 프로세슬 조금씩 실행시켜서 동시에 실행 되는 것처럼 보이게 하는 기술
  • 멀티 프로세싱 : 여러 CPU에 여러 프로세스를 실행시켜서 실행속도를 높이는 기술

하나의 프로세스를 나누서 여러개의 CPU를 넣는 작업을 어떻게 진행할까?

하나의 프로세스에 스레드를 나눠서 각가의 CPU에 넣는 방법을 사용할 수 있다. Thread는 멀티 코어 환경에서 실행 속도를 높이는데 기여할 수 있다.


Thread 의 장점

  1. 사용자에 대한 응답성 향상 : 특정 작업을 위한 스레드를 만들고, 사용자와 커뮤니케이션을 위한 스레드를 만들어서 사용자와 상호작용 하면 응답성이 높아진다.
  2. 자원 공유가 효율적이다. : 프로세스 안에서 나누어 지기 때문에 자원 공유를 위한 별도의 작업을 안해도 된다.
  3. 작업이 분리되어 코드가 간결하다.

Thread 의 단점

프로세스안에서 여러 프로세스를 나누기 대문에 하나의 스레드의 문제가 생겨도 감싸고 있는 프로세스의 문제가 생긴다.

리눅스 os에 경우 thread를 프로세스와 같이 처리하기 때문에 스레드가 많아지면 컨텍스트 스위칭이 많이 일어나고 이에 따라 성능이 저하될 수 있다.


동기화 이슈

프로세스 내에서 같은 공간을 공유 하기 때문에 스레드 간 동기화 이슈가 있다.
하나의 스레드가 오래 걸리는 작업을 수행하는데 컨텍스트 스위칭이 실행됬다면 공유하는 메모리에 저장하기도 전에 다른 스레드에서 작업이 실행될 것이다.
원하는 동작을 지원하지 않게되고 이런 이유로 동기화 이슈가 생긴다.


해결 방법

mutual excrusion

임계 영역을 설정하고 한번에 한스레드만 접근할 수 있도록 설정한다.

1
2
3
4
5
6
def thread_main():
global g_count
lock.acquire() # 임계영역 설정
for i in range(1000000):
g_count=g_count + 1
lock.release() # 임계영역 해제

컨텍스트 스위칭이 일어나도 임계영역에서는 하나의 스레드만 실행 되기 때문에 지금 실행할 스레드에서 전에 실행중인 스레드에 임계영역에 접근할 수 없다.
전에 스레드에서 임계영역을 빠져나오면 키를 다음 스레드에 넘겨주는 형식이라고 생각하면 된다.


Mutex와 세마포어

mutal excrusion 에서 임계 구역에 하나의 스레드만 들어갈 수 있으면 Mutex(binary semaphore) 라고 한다.

반대로 임계 구역의 여러개의 스레드가 들어갈 수 있으면 Semaphore 라고 한다.
counter를 두어서 동시에 들어갈 수 있는 스레드 수를 제어한다.


세마포어

  • P: 검사 (임계 영역에 들어갈 때)
    • s 가 0이 아니면 들어가고 s를 1 차감
  • V: 증가 (임계 여역에서 나올 때)
    • s에 1를 더하고 나옴.
  • S: 세마포어 값 (초기 값만큼 여러 프로세스가 동시 임계 영역에 접근 가능)

세마포어-바쁜대기

s가 0이라면 임계영역에 들어가기 위해 반복문 계속 수행
해결하려면??

세마포어-대기큐

반복문을 돌리지 않고 s값이 0이면 대기큐에 넣고 슬립시킴.
s가 1 이상이 되면 대기큐에서 하나 없애고 깨우며는 방식을 사용한다.


교착 상태(deadlock)란?

무한 대기 상태 : 두개 이상의 작업이 상대방 작업이 끝나기만을 기다리고 있기 때문에, 다음 단계로 진행하지 못하는 상태

기아상태 (starvation)

스레드 각각 우선순위를 지정할때 특정 스레드는 우선순위가 낮다고 가정한다. 그렇게 되면 프로세스를 실행할때 특정 스레드는 계속해서 실행되지 않게 될 수 있는데 이런 상태를 기아 상태라고 한다.

우선순위를 변경하는 방법으로 해결할수도 있고, 우선순위 없이 처리하도록 함으로서 해결할 수 도 있다.