TIL

190423_TIL([OS] Process 와 Thread)

프로세스(Process) 와 스레드(Thread)

  • 수업 중 배운 내용과 여러 블로그를 참고하여 쓴 글 입니다. 아직 많이 부족한 실력이기 때문에 사실과 다른 점이 있을 수 있습니다. 그런 부분을 댓글로 알려주시면 정말 감사하겠습니다.

프로세스(Process)란?

프로그램과 프로세스 정의
  • 프로그램 : 어떤 작업을 하기위해 실행할 파일(하드디스크에 저장되어 있고 하나만 존재) –> ex) notepad.exe
  • 프로세스 : 메인 메모리에 올라와서 실행을 시작한 프로그램 –> ex) 이미 실행되고 있는 notepad(notepad는 여러 개를 실행할 수 있다…! 하나만 존재 X)
프로세스의 특징
  • 프로세스는 Code, Data, Stack, Heap 구조의 독립된 메모리 영역을 할당 받는다.
  • 모든 프로세스는 기본적으로 하나 이상의 스레드(메인 스레드)를 가지고 있다.
  • 원칙적으로 한 프로세스는 다른 프로세스의 메모리에 접근할 수 없다.


스레드(Thread)란?

스레드의 정의
  • 사전적 의미 : ‘프로세스 내에서 실행되는 여러 흐름의 단위’
  • 프로세스가 할당받은 자원을 이용하는 실행의 단위
스레드의 특징
  • Code, Data, Heap 영역을 공유하고 별도의 Stack만 가지고 있다.
  • 각자 별도의 stack이 있기 때문에 각 스레드 마다 실행흐름을 달리 가져갈 수 있다.
멀티스레드의 장*단점
  • 장점

    • 프로세스와 달리 Code, Data, Heap 영역을 공유한다. 그렇기 때문에 작업량이 적고 처리비용이 감소한다.
    • Context Switching 에 대한 오버헤드가 줄어 든다.
  • 단점

    • 디버깅이 어려워진다.

    • 단일 프로세스 시스템에서는 효과를 기대하기 어렵다.

    • 스레드 간의 통신시 데이터를 주고받는 방법은 메모리 공간을 공유하므로 그 공유자원(shared resource)을 이용하여 구현하는데, 공유자원에 각 스레드가 접근 했을 때 Round - robin Scheduling 등에 의해서 context switching이 일어나게 되는데 그 때, 일련의 과정을 보장해주지 않기 때문에 경쟁상태(race condition) 문제가 발생하게 된다.


참고

  • Context Switching : 멀티프로세스 환경에서 CPU가 어떤 하나의 프로세스를 실행하고 있는 상태에서 인터럽트 요청에 의해 다음 우선 순위의 프로세스가 실행되어야 할 때 기존의 프로세스의 상태 또는 레지스터 값(Context)을 저장하고 CPU가 다음 프로세스를 수행하도록 새로운 프로세스의 상태 또는 레지스터 값(Context)를 교체하는 작업
  • Round - robin Scheduling : 정해진 시간(time slice, quantum)동안 프로세스를 실행, 프로세스의 상황은 전혀 고려하지 않고 정해진 시간이 지나면 실행중인 프로세스를 바로 끌어내린다.


경쟁상태 문제해결 예시 with python

  • 문제 해결 방법 : lock을 설정하여 thread간 공유자원 접근을 배제한다. –> 상호배제(mutual exclusion)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
import threading

# 공유 자원
# 모든 스레드에서 접근이 가능한 자원
# 전역 변수

g_num = 0
# lock 개체
lock = threading.Lock()


def thread_main():
global g_num

# critical section
# 임계 영역
# 어떤 스레드에서 공유 자원에 접근한 후
# 수정, 변경 하려는 코드
lock.acquire()
for _ in range(100000):
g_num += 1
lock.release()


threads = []

for _ in range(50):
th = threading.Thread(target=thread_main)
threads.append(th)

for th in threads:
th.start()

for th in threads:
th.join()

# 결과값이 계속 달라진다. --> race condition 문제
# 공유자원에 각각 접근 했을 때 RR 등에 의해서 context switching이 일어날 때, 일련의 과정을 보장해주지 않기 때문에 발생
# 해결책 : 서로가 서로를 공유자원 접근을 배제하게 하면됨---> lock. (상호배제)-- mutual exclusion
print(f'g_num : {g_num}')

참고자료

Share