Threads

Eunji·2025년 4월 13일

Operating System

목록 보기
3/11

Are Processes Enough?

Possible scenarios

  • A server with many clients (e.g. webserber)
    • process: context switching -> overhead
  • A powerful computer with many CPU cores

Problems with Processes

Process creation is heavyweight (i.e. slow)

  • Space must be allocated for the new process
  • fork() copies all state of the parnet to the child
    • memory access -> long time

IPC(Inter Process Communication) mechanisms are cumbersome

  • Difficult to use fine-grained synchronization
  • Message passing is slow
    • Each message may have to go through the kernel
    • process는 세밀한 동기화가 어렵기 때문에 Message passing을 이용해야 하는데, 이는 매우 느림

Threads : a flow of contorl

Light-weight processes that share the same memory and state space

Every process has at least one thread

Benefits

  • Resoures sharing, no need for IPC
  • Economy: faster to create, faster to context switch
    • address space change X -> change EIP, stack, Register
  • Scalability: simple to take advantage of multi-core CPUs

Thread Implementations

Threads can be implemented in two ways

  1. User threads

    • User-level library manages threads within a single process
  2. Kernel threads

    • kernel manages threads for all processes

User Threads and Kernel Threads

User threads - management done by user-level threads library

  • Three primary thread libraries
    • POSIX Pthreads (Linux, Unix)
      • in Linux, Pthread 생성하면 kernel level이 자동 생성되도록 구현됨
    • Windows threads
    • Java threads

Kernel threads - Supported by the Kernel

  • Examples - virtually all general purpose operating systems, including
    • Windows
    • Solaris
    • Linux
    • Mac OS X

Multithreading Models

  1. Many-to-One
  2. One-to-One
  3. Many-to-Many

Many-to-One

  • Many user-level threads mappend to single kernel thread
  • one thread blocking causes all to block

User thread request I/O

  • OS 입장에서는 kernel thread가 I/O인 줄 알고 waiting state 처리
    -> user threads 전부 wait queue에 들어가게 됨
    => CPU wait, scheduling 대상에서 제외되는 문제 발생
  • kernel thread를 지원하지 않는 OS는 process만 보이고, user-level을 여러개 생성하여 처리 -> 문제점이 많아서 현재는 native (kernel thread) 지원
  • Multiple thread may not run in parallel on multi-core system because only one may be in kernel an a time
  • Example
    • Solaris Green Threaads
    • GNU Portable Threads

One-to-One

  • Each user-level threads maps to kernel thread
  • Creating a user-level thread creates a kernel thread
  • More concurrency than many-to-one
  • Number of threads per process sometimes restriced due to overhead
  • Example
    • Windows
    • Linux
      • Pthread 하나 만들면 대응되는 kernel thread 생성
    • Solaris 9 and later

      묶을 수 있으면 multi-core이지만 완전한 light model은 아님
      address space를 공유하는 thread 생성 가능

Many-to-Many Model

  • Allows many user level threads to be mapped to many kernel threads
    • user >= kernel
  • Allows the operating system to create a sufficient number of kernel threads
  • Solaris prior to version 9
  • Windows with ThreadFiber package
    • Fiber(섬유)끼리 context switching
    • kernel thread안에 Fiber(user-level)
  • blocking X -> CPU끼리, I/O끼리 사용

Two-level Model

  • Similar to M:M, except that it allows a user thread to be bound to kernel thread
  • Exmaples
    • IRIX
    • HP-UX
    • Solaris 8 and eariler

POSIX Pthreads

POSIX standart API for thread creation

  • IEEE 1003.1c
  • Specification, not implemention
    • Defines the API and the expected behavior
      Implementation is system dependent
  • On some platforms, user-level threads
  • On others, maps to kernel-level threads

Pthread API

  • pthread_attr_init()
    • initialize the threading library
  • pthread_create()
    • create a new thread
    • similar fork(), exec() 존재 x
      • address copy가 일어나지 않기 때문에 create()에서 code 채움
  • pthread_exit()
    • exit the current thread
  • pthread_join()
    • wait for another thread to exit : 동기화
  • Pthreads also contains a full range of synchronization primitives

Pthread Example

      pthread_t tid; // id of the child thread
      pthread_attr_t attr; // initialization data
      pthread_attr_init(&attr);
      pthread_create(&tid, &attr, runner, 0);
      pthread_join(tid, 0);

void * runner(void * params) {pthread_exit(0);
}
  • create()
    • process's address space share
    • runner: 새로 생성된 스레드가 시작될 때 실행될 함수의 포인터를 넘김
    • 0: runner 함수에 넘길 parameter -> NULL

Linux Threads

In Linux, process와 thread의 명확한 구분이 없음

In the kernel, threads are just task

  • Remember the task_struct from eariler?

New threads created using form clone() API

  • Sort of like fork()
  • Creates a new child task(not process) that copies the address space of the parent
    • Same code, same environment, etc => share space
    • New stack is allocated
    • No memory needs to be dcopied (unlike fork())

Thread Oddities

What happens if you fork() a process that has multiple threads?

  • You get a child process with exactly one thread
  • Whichever thread called fork() survives

What happens if you run exec() in a multi-threaded process ?

  • All but one threads are killed
  • exec() gets run normally
    • 새로운 거로 치환하여 원래 있던 거 전부 날아감, exec()를 부른 애는 남아서 새로운 코드 적재

Advanced Threading

Thread pools

  • Create many thread in advance
  • Dynamically give work to threads form the pool as it becomes available

Advantages

  • Cost of creating threads in handled up-front
  • Bounds the maximum number of threads in the process
    많이 만들면 overhead -> embeded, real-time처럼 overhead 발생 시 급격한 성능 저하가 발생하는 경우 사용

Thread Local Storage

Sometimes, you want each thread to have its own "global" data

  • Not global to all threads
  • Not local storage on the stack

Thread local storage(TLS) allows each thread to have its own space for "global" variables

  • Similar to staic variables
  • in gcc compiler, thread_local()

OpenMP

#include <omp.h>

int main() {
     int i, N = 20;
     #pragma omp parallel
     {
           printf(“I am a parallel region\n”);
     }

     # pragma omp parallel for
     for (i = 0; i < N; i++)
           printf(“This is a parallel for loop\n”);

     return 0;
}

Compiler extensions for C, C++ that adds native support for parallel programming

Controlled with parallel resions

  • Automatically creates as many thread as there

Processes vs Threads

Threads are better if

  • You need to create new ones quickly, on-the-fly
  • You need to share lots of state
    1. multi-core 활용 가능
      • multi-core하고 싶으면 multi-thread-> but protection problem...
      • 한 thread가 잘못되면 process 전체 crash
    2. overhead down \because address space share -> faster context switching

Processes are better if

  • You want protection
    • One process that crashes or freezes doesn't impact the others
  • You need high security
    • Only way to move state is through weel-defined, sanitized message passing interface
    • e.g. Java VM: 하나의 process가 잘못되어도 VM만 crash, OS에는 영향 x

0개의 댓글