본문 바로가기
Computer Science/Operating System

Thread

by Gofo 2021. 6. 18.

Thread

Thread는 execution의 단위로, 스케줄링의 단위이기도 하다.

 

기본적으로 하나의 process 안에는 하나의 thread가 존재한다.

Multithreaded는 하나의 process 안에 여러 개의 thread가 있는 것을 말한다.

 

Memory 관점

Thread는 자신만의 stack을 가져야 한다.

따라서 thread을 사용하면 메모리 구성이 달라진다.

 

Concurrent Function Call

각 thread는 하나의 함수로 이루어져있다.

thread를 생성할 때 함수를 지정해서 생성한다.

예 : <pre>rc = pthread_cureat(&threads[t], NULL, PrintHello, (void*) t);</pre>

 

일반적인 프로그램(single-threaded program)은 하나의 연속적인 흐름으로 실행된다.

 

Multithreaded 프로그램은 프로그램의 흐름이 분리되어 동시에 흘러간다.

main thread와 다른 thread들이 ready queue에 들어가서 스케줄링의 대상이 되고, concurrent하게 실행된다.

 

Process vs. Thread

Process와 thread는 모두 실행의 단위이고 스케줄링의 단위이다.

 

Process는 full resource ownership을 가진다.

address spcae, processor context, control of some resources(file, I/O devices) 등 전체에 대한 ownership을 가진다.

 

반면에 thread는 실행에 필요한 적은 양의 자원을 필요로 한다.

private stack space, processor context에 대한 ownership을 가진다.

code, data, file, I/O device 등 다른 resources들은 process와 공유한다.

 

Thread는 process보다 적은 양의 자원을 필요로 하기 때문에 lightweigth process라고도 한다.

이런 측면에서 전형적인 process는 heavyweight process라고 한다.

 


Pthreads APIs

맨 앞의 p는 posix 표준에서 규정됬다는 의미이다.

일번적인 언어에서는 함수를 concurrent하게 실행하지 않는다.

따라서 별도의 API를 이용해서 thread를 만들어야 한다.

 

다음과 같은 api를 지원한다.

  • pthread_t pthread_self()
    • 자신의 thread id를 반환한다.
  • int pthread_equal(pthread_t t1, pthread_t t2)
    • 두 thread id를 비교해서 같은지 확인한다.
  • int pthread_join(pthread_t thread, void **status_ptr)
    • 다른 thread의 작업이 끝날 때 까지 기다린다.
  • int pthread_detach(pthread_t thread, void **value_ptr)
    • thread가 종료될 때 모든 자원을 반환한다.

 


Thread의 특징

Thread의 실행은 다음과 같은 특징을 가진다.

  • Thread는 상태(state)를 가진다.
    • running
    • ready
    • waiting
  • 실행될 때 context switching 가 필요하다.
  • address space(code + data) 와 프로세스의 자원들을 공유한다.
    • data 영역에는 global variable을 저장한다.
    • 한 thread가 global variable의 값을 변경한다면 다른 thead에서도 변경된 값을 이용하게 된다.

 

Thread Private Data vs. Thread Local Data

Thread Private Data

각의 thread들이 독립적으로 가지고 있는 stack에 저장되는 data 들이다.

stack에는 local variable, 함수 호출에 필요한 arugment, return value들이 저장되어있다.

이들을 private data라고 한다.

 

Thread Local Data

global variable이지만 thread 마다의 local variable 처럼 작동하는 data 들이다.

이렇게 작동하기 위해서는 global variable 앞에 <pre>__thread</pre>를 붙여야 한다.

<pre>__thread void *mydata;</pre> 가 global variable로 선언되어있어도 thread 마다의 local variable 처럼 작동한다.

 

원본은 하나이지만 thread 마다 copy 해서 사용하는 것이다.

각 thread에서 다른 thread에서의 값을 읽거나 쓰지 못하게 된다.

 

Thread 사용의 장점

Thread를 사용하면 다음과 같은 이점을 얻을 수 있다.

  • responsiveness (응답성)
    • single thread 프로그램에서는 프로세스가 waiting 상태 동안 아무 작업을 하지 못하고 기다려야 한다.
    • 보통 running time 보다 waiting time이 더 길기 때문에 이로인해 성능이 낮아지게 된다.
    • thread를 사용하면 waiting 시간 동안 다른 therad를 수행함으로써 성능을 높일 수 있다. 
  • resource sharing
    • thread는 memory(code, data)와 resource를 공유한다.
    • 따라서 thread는 프로세스에 비해 더 적은 자원으로 일을 처리할 수 있다.
  • economy
    • 더 적은 자원을 소모함으로써 economy를 높일 수 있다.
    • 공유자원을 사용함으로써 thread 간의 communication cost를 줄일 수 있다.
    • communication은 단지 global variable에 read/write 하기마나 하면 된다.
    • shared memroy, passing message 등을 구현할 필요가 없어진다.
  • utilization of multiprocessor architecture
    • multiprocessor를 최대한 활용할 수 있게 된다.
    • 여러 개의 CPU가 있더라도 1개의 프로세스는 하나의 CPU에서만 동작한다.
    • 그러나 thread를 이용하면 여러 CPU를 동시에 이용할 수 있게 된다.
  • concurrent programming model
    • 전통적인 프로그래밍에서는 concurrent programming을 하지 않고 모든 일을 sequential 하게 처리한다.
    • 때문에 동시에 발생하는 사건이나 동시에 실행해야 하는 작업들을 처리하기 힘들다.
    • thread를 사용하면 이에 대한 설계/구현이 쉬워진다.

 


Multithreading and Web

Web Server

보통 web server는 동시에 수많은 접속자들이 들어온다.

따라서 concurrent programming 을 해야 한다.

 

이를 위해서 접속자 수와 동일한 프로세스를 생성(fork() 이용)하거나, thread를 생성해야 한다.

Thread는 프로세스에 비해서 더 많은 장점이 있기 때문에 thread를 이용하는 것이 좋다.

 

아래 그림에서는 dispathcer thread가 최초로 사용자 접속을 응대하고 worker thread에게 작업을 할당하고 처리하게 한다.

 

Web Browser

각각 클릭되어야 하는 요소들에 대해 thread를 이용해서 처리할 수 있다.

이는 프로세스를 이용하는 것에 비해 이점이 있다.

 


Thread Issue

fork() system call

두 가지 모두 사용되는 방법이다.

  • fork를 호출한 thread 만을 복제할 것인가
  • 다른 thread들 도 다 복제할 것인가

 

다른 system call

thread들은 자원을 공유하기 때문에 race가 일어나지 않도록 api를 바꿔줘야 한다.

  • thread들은 file descriptor를 공유한다.
    • locking protocol을 이용해야 한다.
  • address space(code, data)를 공유한다.
    • system call을 thread-safe 하게 바꿔야 한다.

 

Stack Overflow

특히 user thread를 사용할 때 발생한다.

  • stack 전체 영역이 data를 침범한다면 kernel이 exception 시킨다.
  • stack 간에 침범을 한다면 kernel은 detect하지 못한다.
  • kernel 입장에서 multi-user thread들은 하나의 프로세스로 취급당하기 때문이다.
  • 대부분의 라이브러리가 이러한 위험을 방지하지만, 그렇지 않은 경우도 있다.

 


Thread Pool

multithreading를 할 때 최적화하는 기법이다.

특히 web server multithreadign에서 유용하게 사용된다.

 

미리 필요한 만큼의 thread를 만들어놓고 thread를 사용할 때 미리 만들어진 것을 이용하는 방법이다.

thread의 작업이 완료되면 다시 pool로 돌아간다.

 

Thread pool을 이용하면 새로운 thread를 creat 하는 것 보다 더 빠르게 작업할 수 있다.

 

 

 

'Computer Science > Operating System' 카테고리의 다른 글

CPU Scheduling  (0) 2021.06.19
Multi-threading  (0) 2021.06.18
Cooperating Processes  (0) 2021.06.17
프로세스 생성/종료  (0) 2021.06.17
Process Scheduling (Context Switching)  (0) 2021.06.16

댓글