OS_06_Threads

saewoohan·2023년 7월 28일
0

OS

목록 보기
6/19
post-thumbnail

OS_06_Threads

1. Thread Concepts

1) Concepts

  • thread는 lightweight process라고 불린다.
    • thread는 execution의 unit (scheduling의 대상)
    • thread는 최소한의 자원만을 필요로한다.
    • 기존의 process는 heavyweight process라고 불린다.

single thread and multithread

single-thread and multithread

  • stack을 thread들이 따로 가진다는 것의 의미 → 별도의 함수 호출을 thread마다 가진다는 의미이다.
    • Special한 function call (concurrent → caller와 callee가 같이 진행하는 function)

2) Processes vs. Threads

  • Processes
    • Unit of execution (scheduling unit)
    • 모든 자원을 가지고 있다.
      • address space와 processor context를 가지고 있다.
      • 몇몇개의 resources의 control을 가진다.
  • Threads
    • Unit of execution (sheculing unit)
    • execution을 위한 최소한의 자원만 가지고 있다.
      • private stack space and processor context
      • 다른 자원들은 프로세스와 공유한다.

Single vs. multi threaded application

3) Thread example - Create and Exit

#include <pthread.h> 
#include <stdio.h>
#define NUM_THREADS 5

void *PrintHello(void *threadid) 
{
	printf("\n%d: Hello World!\n", threadid);
	pthread_exit(NULL); 
}
int main (int argc, char *argv[]) 
{
	pthread_t threads[NUM_THREADS];
	int rc, t;
	for(t=0;t < NUM_THREADS;t++){
		printf("Creating thread %d\n", t);
		rc = pthread_create(&threads[t], NULL, PrintHello, (void *)t);
		if (rc){
			printf("ERROR; return code is %d\n", rc);
			exit(-1); 
		}
	}
	pthread_exit(NULL);
}
int pthread_create(pthread_t *thread_id, const pthread_attr_t *attr, void *(*thread_function)(void *), void *arg);
  • 새로운 tID를 thread_id argument를 통해서 return한다.
  • attr인자는 thread의 attribute를 결정하기 위해 사용된다. thread attribute object를 규정하거나 default value를 나타내는 NULL을 사용할 수 있다.
  • thread_func는 C routine이다. thread가 만들어 질 때, 실행 되는 부분
  • arg는 single argument → start_routine에 전달이 된다.

4) Pthreads APIs

  • pthread_t pthread_self()
    • 자기 자신의 tid를 가져온다.
  • int pthread_equal (pthread_t t1, pthread_t t2)
    • 2개의 tid를 비교한다.
  • int pthread_join (pthread_t thread, void ** status_ptr)
    • 다른 thread가 끝날 때 까지 기다린다
  • int pthread_detach (pthread_t thread; **valut_ptr)
    • 종료되면 resource가 자동으로 회수 할 수 있다는 것을 표시한다.
    • 다른 thread가 join 할 수 없다는 것을 의미한다.

5) Execution Properties of Threads

  • Thread는 execution state를 가진다 (running, ready, waiting)
    • 이 또한 scheduling의 대상이기 때문에.
  • Thread는 context switching을 필요로한다.
  • Thread는 address space (code and data) 와 resource를 공유한다.
    • 한 thread가 전역 변수를 변경하면, 다른 모든 thread에서 그 변화를 볼 수 있다.
    • thread에서 열린 파일은 다른 thread에서도 이용할 수 있다.

6) Thread Private Data

  • stack영역에 있는 variable들은 thread-private data이다.
    • function에 넘겨진 parameter들도 thread-private data이다.
double func (double a)
{
	double b;
...

7) Thread Local Variables

  • thread-local 변수는 모든 routine에서 볼 수 있는 global data이다.
  • 하지만, 각 thread는 각자의 사본 data만을 볼 수 있다.
__thread void *mydata;

void * threadFunction (void * param)
{
	mydata = param;
...

8) Benefits of Threads

  • Responsiveness
    • thread를 사용한다는 것은 한 부분이 block상태여도 프로그램이 계속해서 실행 될 수 있음을 뜻함
  • Resource sharing
    • Thread들은 memory와 resource를 공유한다.
  • Economy
    • 생성과 context switch가 경제적이다.
  • Utilization of multiprocessor architectures
    • Multithreaded process는 동시성을 향상시킬 수 있다!
  • Concurrent programming model

2. Multithreading Models

1) User Threads

  • Thread 관리
    • user-level(user space)에서의 thread library에 의해
    • kernel의 supprot가 없다.
  • Strength
    • 일반적으로 create와 manage가 빠르다 (mode switching cost가 없기 때문에)
  • Drawback
    • 만약 커널이 single thread라면, 어떠한 user-level thread가 blocking system call을 수행한다면 모든 process가 block되는 상황을 야기할 수 있다.
  • Examples
    • POSIX Pthreads, Mach C-threads

2) Kernel Threads

  • Thread 관리
    • kernel에 의해 직접적으로
    • kernel이 thread creation, scheduling, management를 kernel space에서 수행한다.
      • create와 manage가 user thread보다 느리다.
  • Examples
    • Windows 95/98/NT/2000
    • Solaris
    • Tru64 UNIX
    • BeOS
    • Linux

3) Multithreading Models

Many-to-One, One-to-One, and Many-to-Many

  • Many-to-one
    • 여러개의 user-level thread들이 하나의 kernel thread에 mapping된다.
    • kernal thread를 지원하지 않는 system에서 사용된다.
  • One-to-one
    • 각기의 user-level thread가 kernel thread에 mapping 된다.
    • Examples
      • Windows 95/98/NT/2000, OS
  • Many-to-many
    • 여러개의 user-level thread가 여러개의 kernel-level thread에 mapping된다.
    • OS가 충분한 숫자의 kernel thread를 만드는 것을 허용한다.
    • Examples
      • Solaris 2, Windows NT/2000 with the ThreadFiber pacakage

3. Threading Issues

1) Threading Issues - fork

  • fork() system call의 의미
    • 하나의 thread가 fork를 수행한다면 두 가지의 가능성이 있다.
      • 새로운 Process가 모든 thread들을 복사한다.
      • 새로운 process는 single-thread가 될 수 있다.
    • 많은 system은 두가지의 fork()의 변형을 제공하여 타협한다.

2) Threading Issues - Other System Calls

  • 모든 thread들은 file descriptor들의 집합을 공유한다.
    • 만약 하나의 thread가 다른 thread가 현재 쓰거나 읽고 있는 도중에 file을 닫는다면?
    • 그래서 우리는 file locking protocol이 필요하다.
  • process에 있는 모든 thread들은 공통의 주소 공간을 공유한다.
    • 만약 이 주소 공간을 동시에 변경한다면? (mmap, sbrk)
    • 이러한 system call들은 반드시 thread-safe해야한다.

3) Threading Issues - Stack Overflow

  • 만약 UNIX process에서 stack overflow가 발생한 경우
    • segmentation violation fault로 이어진다.
    • kernel이 fault를 인식하고 process에게 signal을 보내는 대신 자동적으로 할 수 있는 최대한의 제한 까지 stack을 확장한다.
  • user thread인 경우 kernel은 user stack에 대해서 알지 못한다.
    • thread는 일반적으로 필요한 stack의 size를 규정한다.
    • stack은 user thread library에 의해 할당된다.
    • library는 write-protected page를 stack의 끝부분에 할당하면서 overflow에 대해서 보호한다.
    • stack overflows가 발생했을 때, protection falut를 야기하고, kernel은 적절한 thread에 ‘SIGSEGV’ signal을 보내면서 반응한다.

4) Threading Issues - Thread Pool

  • A pool of threads
    • 프로세스 시작 단계에서 여러개의 thread들을 만들고 pool에 넣는다.
    • process가 요청을 받는다면, pool에 service를 요하는 요청을 보내면서 pool에 있는 thread를 깨운다.
    • thread가 역할을 다하게 된다면, pool에 돌아간다.
    • Benefits
      • 새로 thread를 만드는 것보다 service request를 보내는 것이 더 빠르다.
      • 많은 숫자의 thread가 동시에 수행되는 것을 막으면서, system에 thread개수 제한을 둔다.
    • Web server multithreading에 유용하다.

4. Examples

  • Solaris 2 Threads
    • Solaris 2는 kernal and user level의 thread들의 지원을 제공한다.
      • user and kernel level thread 들 사이에 lightweight process가 존재한다.
    • LWP
      • kernel은 user thread를 supprot한다.
      • 각기의 process들은 적어도 하나의 LWP를 가진다.
      • thread library는 LWP의 pool에 있는 user-level thread들을 다중화(?)한다.

Many to many 사실상 kernel thread들을 가상의 CPU로 볼 수 있다.

  • Kernel-level threads
    • 각기의 LWP는 kernel-level thread를 가진다.
    • 몇몇의 kernel level thread들은 LWP와 관련이 없고, kernel을 대신하여 수행한다.
    • kernel-level thread들은 system안에서 schduling되는 유일한 객체들이다.
  • User-level threads (bound or unbound)
    • A bound user-level thread는 영구적으로 LWP에 붙어 있다.
      • response time이 빠르다 (real-time applications)
    • application에 있는 모든 unbound thread들은 application을 위해 이용할 수 있는 LWP들의 pool에 의해 다중화(?)된다. (자유롭게 필요할때 할당받는다.)
      • thread들의 기본값은 unbound

0개의 댓글