CafeM0ca

[OS] 공룡책 Chapter4 스레드 본문

OS/공룡책

[OS] 공룡책 Chapter4 스레드

M0ca 2021. 1. 21. 04:25
반응형

챕터4 스레드

스레드는 thread id, program counter(PC), register set, stack으로 이루어져 있다.

스레드는 같은 프로세스의 포함되어 코드 영역, 데이터 영역, 열린 파일이나 시그널과 같은 운영체제 리소스를 공유한다.

Parallelism의 종류

  • Data parallelism

    • 데이터를 쪼개서 연산을 수행하는 것

    • 배열이라는 데이터가 있으면 반으로 쪼개서 2개의 작업으로 나눠 연산 진행

  • Task parallelism

    • 스레드간 각각의 고유한 일을 맡아서 처리하는 것

       

thread의 cancellation(취소)

취소되어야 할 스레드를 target thread라고 부른다.

두 가지 방식으로 취소할 수 있다.

  1. asynchronous cancellation : 한 스레드가 목적 스레드를 즉시 강제 종료시킨다.

  2. deferred cancellation : target thread가 주기적으로 자신이 강제 종료되어야 하는지 검사한다.

비동기식 취소는 시스템 자원을 모두 회수할 수 있는 보장이 없다.

deferred cancellation(지연 취소)의 경우에는 스레드를 취소하기 위해 플래그를 검사하여 취소해도 괜찮은 시점을 잡는다. Pthread에서 이를 cancellation point라고 부른다.

thread pools

스레드 풀은 스레드를 처음에 만들어놓고 필요할 때 pool에서 스레드를 꺼내서 사용하는 방법이다. pool에 task가 들어오면 비동기적으로 작동할 수 있다.

스레드 풀이 제공해 주는 이점은 다음과 같다.

  1. 스레드가 존재할 때 작업을 서비스 하는건 스레드 생성을 기다리는 것 보다 빠르다.

  2. 스레드 풀은 특정 시점(e.g 풀이 생성될때)에 스레드의 최대 개수를 제한한다 . 이는 시스템에서 꽤 중요한 부분이며 시스템은 현재 스레드보다 많은 스레드를 제공할 수 없다.

  3. 수행할 task를 task 생성 메커니즘으로부터 분리하면 task 실행을 위한 다양한 전략을 사용할 수 있다. 예를 들면 task를 지연시키거나 주기적으로 실행하도록 스케쥴링할 수 있다.

Threading issues

fork()와 exec()를 스레딩과 관련지어 알아보자.

fork()

스레드가 fork()를 호출하면 새 프로세스는 모든 스레드를 복제할까? 아니면 새 프로세스는 싱글 스레드로 돌아갈까?

몇몇 UNIX 시스템은 두가지 버전의 fork()를 갖고 있다. 하나는 모든 스레드를 복제하는 것, 다른 한 가지는 fork()를 호출한 스레드만 복제하는 것이다.

exec()

exec()가 fork() 직후 호출된다면 exec()에 지정될 매개변수들이 프로세스를 대체할 것이므로 복제된 스레드들은 필요없어진다. 이 경우에는 모든 스레드를 복제하는 것이 아닌, 호출한 스레드만 복제하는 것이 맞다. 그러나 fork() 이후 exec()가 호출되지 않는다면 모든 스레드를 복제하는게 맞다.

signal handling

signal은 UNIX에서 사용하는 프로세스에게 이벤트를 발생시키기 알리기 위한 것이다.

모든 시그널은 동기/비동기 상관없이 아래 순서의 패턴을 따른다.

  • 특정 이벤트의 발생으로 생성

  • 프로세스에게 전달

  • 한번 전달되면 시그널은 반드시 핸들되어야 한다.

default signal handler

모든 시그널은 default signal handler가 있다.(user-defined signal handler도 있음)

커널에서 작동하며 시그널을 핸들링한다.

default signal handler는 override하여 user-defined signal handler로 만들 수 있다.

싱글스레드 프로그램에서 시그널을 핸들링 할 때 시그널은 항상 전달된다.

멀티 스레드 프로그램에서는 시그널 핸들링은 프로세스는 여러 스레드를 갖고 있는데 어떤 스레드에게 시그널을 전달해야하는지 문제가 생긴다.

일반적으로 아래 옵션이 있다.

  1. 시그널이 적용되는 스레드에게 전달한다.

  2. 프로세스에 있는 모든 스레드에게 시그널을 전달한다.

  3. 프로세스에 있는 특정 스레드에게 시그널을 전달한다.

  4. 프로세스에 대한 모든 신호를 수신하려면 특정 스레드를 지정한다.

APC(asynchronous procedure call)

scheduler activations

멀티스레딩에서 커널과 스레드 라이브러리간의 통신에 대해서 알아보자.

많은 시스템이 n:m이나 유저-커널과 같은 two-level 모델을 사용한다. 이 자료구조는 lightweight process(LWP)라고 불린다.

LWP는 가상 프로세서로 어플리케이션을 user thread가 실행할 수 있도록 스케쥴링할 수 있다. 각각의 LWP는 커널 스레드에 연결되고 LWP는 운영체제가 물리적 프로세서에서 스케쥴하여 커널스레드를 실행할 수 있게한다.

만약 커널 스레드가 I/O와 같이 기다리는 것에 block되면 LWP도 block된다. 이에 대한 영향으로 user-level에 연결된 LWP도 block된다.

user-thread와 kernel-thread의 통신 방식 중 하나는 scheduler activation으로 알려져 있으며 다음과 같이 동작한다.

  • 커은 어플리케이션에 가상 프로세스(LWP) 집합을 제공한다.

  • 어플리케이션은 user-thread가 가상 프로세스에 접근할 수 있도록 스케쥴할 수 있다.

  • 커널은 반드시 어플리케이션에게 특정 이벤트를 알려야한다.

  • 이 작업을 해주는 프로시져는 upcall로 알려져있다. upcall은 스레드 라이브러리의 upcall handler에 의해 핸들링되며 upcall handler는 반드시 가상 프로세스에서 동작한다.

요약하면

이에 대해서 자세히 알고자 하려면 https://m.blog.naver.com/PostView.nhn?blogId=x21999&logNo=220767565982&proxyReferer=https:%2F%2Fwww.google.com%2F를 참조하자.

반응형
Comments