1. 스레드란?

  • 프로세스가 할당받은 자원을 이용하는 실행 흐름의 단위.
  • 공유 자원 : 주소 공간, Code, Data, Heap, 열린 파일, 신호
  • 별도 자원 : register와 Stack
  • 자원의 생성과 관리의 중복성을 최소화하여 수행 능력을 향상
  • 한 스레드의 결과가 다른 스레드에 영향을 끼친다.

User-level thread

  • 장점 : 빠르다
  • system call이나 I/O 가 발생해서 Block 되면, 프로세스 자체가 block 되었다고 판단하여, 다른 스레드도 돌릴 수 없다. → CPU 안 쓰게 된다.
  • 무한 루프 돌고 있어서 자원을 계속 차지하고 있어도, 뺏어올 수 없음 → 자발적으로 넘겨줘야 함

Kernel-level thread

  • 단점 : 느리다.
  • OS 가 알아서 thread 가 block 되면 다른 thread로 CPU를 할당함

 

2. 멀티 스레드

  • 멀티 스레드를 제공한다면, CPU를 점유하는 가장 작은 단위 = 스레드가 됨
  • 즉, Parallel 한 작업
  • 한 개의 단일 애플리케이션은 여러 스레드로 구성 후 작업 처리해야 한다.
  • 한글에서 싱글 스레드를 사용하면, 프린트를 하는 경우 문서 수정은 불가능하다.
  • 디버깅이 어렵다. 자원 공유 문제(교착상태)가 생긴다.

우리가 컴퓨터 살 때 보는 '6 코어 12 스레드'에서 스레드는 물리적인 코어 6개로 12개의 스레드를 동시 멀티스레딩(SMT, Simultaneous Multi-Threading)으로 구현이 된 것이라고 한다 (하이퍼스레딩이 있는 CPU라고 한다). 즉 S/W의 관점으로는 하나의 코어에 하나의 가상의 코어를 만들어서 CPU 2개로 인식된다. 

 

즉, 물리적인 Core 위에 하이퍼스레딩으로 구현된 (물리적이라고 볼 수 있는) Core 스레드가 여러 개 존재하고, 그 위로 Kernel-level 스레드가 더 여러개 있을 수 있고, 그 위로는 User-level 스레드가 더더 여러개 있을 수 있는 구조가 되겠다. (물론 어떤 멀티 스레드 모델이냐에 따라 다를 수 있다.)

멀티 스레드 모델

 

 

3. Context-Switching : 프로세스 vs 스레드

  • 프로세스는 운영체제로부터 자원을 할당받아 실행하고, 스레드는 프로세스로부터 자원을 할당받아 실행합니다.
  • 프로세스 : fork()를 통해 생성되는데, 매번 동일한 코드가 복사되어 작동하고, PCB, 주소 복사 등 Context Switching에 Cost가 크다.
  • 스레드 : 레지스터와 스택을 제외하고 자원을 공유하여 사용 → 한 가지 스레드는 I/O를 담당하는 등, 스레드로 각 CPU에 일을 할당해서 수행 가능

 

 

4. 멀티 프로세스 vs 멀티 스레드

1. 멀티 프로세스

  • Concurrency 한 작업

 

2. 멀티 스레드

  1. 멀티 프로세스보다 자원을 효율적으로 사용 가능
    • 멀티 프로세스로 실행하던 작업을 멀티 스레드로 실행하면, 프로세스를 생성하여, 자원을 할당하는 시스템 콜이 줄어든다
    • 메모리를 공유하기 때문에, 프로세스 간 통신 방법에 비해 스레드 간의 통신 방법이 간단하다.
  2. 처리 비용 및 응답 시간 단축
    • context-switching 시 발생하는 오버헤드를 감소시킬 수 있다.
    • 심지어 스레드의 context switch는 프로세스 context switch 와는 달리 캐시 메모리를 비울 필요가 없다.
  3. 문제점
    • 멀티 프로세스 기반으로 프로그래밍할 때는 프로세스 간 공유하는 자원이 없기 때문에 동일한 자원에 동시에 접근하는 일이 없었지만 멀티 스레딩을 기반으로 프로그래밍할 때는 이 부분을 신경 써줘야 한다. 서로 다른 스레드가 데이터와 힙 영역을 공유하기 때문에 어떤 스레드가 다른 스레드에서 사용 중인 변수나 자료구조에 접근하여 엉뚱한 값을 읽어오거나 수정할 수 있다.
  4. 해결
    • 멀티스레딩 환경에서는 동기화 작업이 필요하다. 동기화를 통해 작업 처리 순서를 컨트롤하고 공유 자원에 대한 접근을 컨트롤하는 것이다. 하지만 이로 인해 병목현상이 발생하여 성능이 저하될 가능성이 높다. 그러므로 과도한 락으로 인한 병목현상을 줄여야 한다.

 

5. Thread 관련 예시

(질문1) 워드에서 글자를 입력했을 때 어떤 일이 발생하는가?

  • 사용자 입력 → 외부 Interrupt 중 I/O Interrupt 발생 → CPU 인지 → CPU 작업 중이던 상태 저장 → 해당 인터럽트 처리 → 상태 복구 및 중단되었던 작업 재개

개인적으론 이 질문이 크롬에 사이트 url을 입력했을 때 일어나는 일을 설명해보라는 질문과 동급이라고 생각한다. 이 질문에 대해 대부분의 글들에선 위처럼 단순히 Interrupt에 대해서만 설명하고, 그대로 복사해오는 것 같아서 나름대로 깊게 생각을 해보았다. 

  • 우선 내 생각은 워드라는 프로세스는 멀티 스레드로 구현이 되어있다고 생각이든다.
  • 그렇게 생각한 이유는 커서가 깜박이고, 입출력을 행할 때 다른 행동을 동시에 할 수 있기 때문이다.
  • 따라서 I/O를 처리할 스레드를 만들었을 것이고, 해당 스레드에서 I/O 인터럽트가 걸릴 것이라 생각이 된다.
  • 헌데 I/O 인터럽트가 걸렸다고 해서 해당 프로세스가 통째로 blocked 되지는 않으므로 하나의 커널 스레드만 사용 중인 것은 아닐 것 같다.
  • 즉, 1:1 혹은 m:n으로 스레드 매핑이 이루어져 있을 것 같다.
  • 인터럽트가 발생한 스레드는 이후 인터럽트 처리 과정이 이루어질 것이다.
  • 실행 중이던 스레드가 실행이 중단되고, TCB에 context를 저장한 후, 인터럽트 원인을 판별 -> 인터럽트 벡터 테이블을 참조 -> ISR(인터럽트 서비스 루틴) 처리 -> Interrupt 처리 종료 후 ready 큐에 있는 작업을 실행하면서 상태를 복구할 것 같다.
  • 이후에 화면에 출력해주는 Interrupt가 걸려서, 또다시 같은 과정을 통해 화면에 그려줄 것으로 예상된다.

이후에 더 공부하면서 추가/수정 한 부분

  • 워드 프로세서는 3가지의 스레드를 가진다
    1. interactive 스레드
    2. Reformatting 스레드
    3. Disk-backup 스레드
  • DMA를 이용하여 I/O를 모아서 처리한다.
    • 출력하려면 마지막에 CPU가 인터럽트를 받아서 출력장치에 값을 넘겨줘야 한다.
    • 이때 문제는 한 글자가 4개 블락으로 돼있으면 한 블락당 검사를 해서 4번의 인터럽트가 걸린다고 볼 수 있는데
    • DMA가 이 검사를 대신해줘서 CPU는 한 번의 인터럽트만 받게 된다!
  • 모니터에 화면을 보여주는 것을 계속 I/O Interrupt 가 발생할까?
    • 화면 출력도 프린터 출력하는 거랑 비슷하게 cpu 거쳐가서 커널 스레드가 하드웨어한테 작업을 부여해줄 뿐 실질적인 출력 실행에는 cpu가 쓰이지 않는다.


(질문2) Chrome 은 멀티 프로세스일까? 멀티 스레드 일까?

이에 대한 정말 정확하고 명쾌한 설명이 담긴 아티클을 첨부하겠다

https://d2.naver.com/helloworld/2922312

 

 

 

Reference

- https://d2.naver.com/helloworld/2922312

+ Recent posts