Post

[운영체제] 5주차 과제

1. ‘프로세스와 스레드의 차이점이 무엇인지 설명해보라’ 이것은 작년 넥슨의 채용계약형 인턴 선발에서 나온 질문이다. 프로세스와 스레드의 차이점을 간단히 설명하고, 멀티태스킹 프로그램을 작성하기 위해 여러 프로세스를 생성하는 것보다 멀티 스레드를 생성하는 것이 왜 나은 것인지, 개발자의 입장과 컴퓨터 시스템의 입장에서 구분하여 구체적으로 설명하라.

  • 과거의 실행단위는 프로세스였다. 하지만 멀티 태스킹에서 여러 문제점 때문에 현재의 실행단위는 스레드이며 이는 프로세스보다 작은 실행단위이다. 프로세스는 스레드의 컨테이너의 역할을 수행한다. 프로세스는 독립적인 메모리 공간을 할당 받아 실행되고, 스레드는 프로세스의 주소 공간을 나누어 사용한다.
  • 멀티 태스킹 환경에서 프로세스는 각각 독립된 메모리 공간에서 실행되기에 각 프로세스는 다른 프로세스에 접근할 수 없어 통신에 어려움을 겪었지만 스레드는 프로세스 메모리 공간을 나누어 사용하기 때문에 프로세스에 속한 스레드들끼리 상호 데이터를 주고받는데 매우 편리한 환경을 제공한다. 따라서 개발자는 프로세스 간 통신에 어려움 겪던 문제를 해소하여 데이터 공유 및 통신이 간단하다 .
  • 프로세스 생성 시 프로세스 관리를 위한 구조체 생성, 초기화 되는데 시간이 많이 걸리고 현재 프로세스를 중단하고 다른 프로세스를 실행시키는 컨텍스트 스위칭에 시간적 공간적 오버헤드가 크다. 하지만 스레드는 프로세스 보다 작은 실행 단위로 프로세스 생성, 소멸에 따른 오버헤드가 적고 빠른 컨텍스트 스위칭이 가능하여 컴퓨터 입장에서 CPU 효율성이 높아진다. 이는 멀티 태스킹 환경에서의 성능이 더 좋아지기 때문에 개발자에게도 좋은일이다.

2. 스레드 컨텍스트란 어떤 정보를 말하는가? 그리고 이 정보는 어디에 저장되는가?

  • 스레드가 현재 실행중인 일체의 상황을 말하며 이는 CPU가 스레드를 실행하고 있을 때 CPU의 레지스터 값들이다. CPU의 PC 레지스터 값 - 스레드가 스케줄될 때 실행할 명령의 주소, SP 레지스터 값 - 스레드 스택의 톱 주소, 스레드가 중지될 때의 여러 CPU 레지스터 값들으로 TCB에 저장된다.

3. 스레드의 주소 공간에 대해

1) 스레드의 주소 공간은 ( )에 만들어진다. 괄호에 들어갈 내용은?
  • 프로세스의 주소 공간
2) 하나의 스레드가 실행되기 위해 주어지는 주소 공간은 어떤 영역으로 나뉘는가? 각각에 대해 간단히 설명하라.
  • 스레드 코드영역 - 프로세스의 함수가 스레드의 코드가 되기 때문에 스레드가 실행할 코드는 프로세스 코드 영 역 내에 있다. 그리고 프로세스의 코드 영역에 적재된 모든 함수들은 모든 스레드가 호출할 수 있다
  • 스레드 데이터영역 - 스레드가 사용할 수 있는 데이터 공간은 프로세스 데이터 공간 전체이다 스레드들이 상호 데이터를 주고받기 위한 공간으로 사용되기 때문이다.
  • 스레드 힙 영역 - 프로세스에 속한 모든 스레드들이 동적 할당받는 힙 공간으로 공유된다. 힙은 스레드 간에 데이터를 주고받는 통신 장소로도 사용된다.
  • 스레드 스택영역 - 사용자 모드에서 호출한 함수들의 매개변수들과 지역변수 등을 독립적으로 저장하기 위한 공간으로 스레드의 사적 공간이다
  • 스레드 로컬 스토리지 - 자신만 사용할 수 있는 특별한 변수들을 선언할 수 있는 는 대체로 힙이나 스택 영역에 할당된다.3) 이 중에서 다른 스레드와 공유하지 않고 스레드만 사용하는 공간은 ( )이다. 괄호에 들어갈 내용은?

  • 스레드 스택, 스레드 로컬 스토리지 (TLS)

4. 프로세스 1에 속한 스레드에서 프로세스2에 속한 스레드로 컨텍스트 스위칭이 일어나는 경우가, 프로세스1에 속한 다른 스레드로 컨텍스트 스위칭되는 경우에 비해 추가적으로 더 필요 한 작업은 무엇인가?

  • 프로세스가 교체되면 CPU가 실행 하는 주소 공간이 완전히 바뀌는 큰 변화가 일어난다. 
  • (1) 메모리 관련 오버헤드
    • 프로세스의 논리 주소를 물리 주소로 매핑하는 MMU 장치 내 이전 맵 테이블을 제거 후 새로운 프로세스의 맵 테이블로 적재하고, 이 과정에서 새로운 프로세스의 코드나 데이터가 메모리에 없어 하드디스크에서 메모리로 옮겨오는 과정이 발생하기도 한다. 또 CPU내 현재 프로세스의 TLB를 모두 비두고 CPU에 새 프로세스의 TLB를 채우는 작업이 필요하다
  • (2) 추가적인 캐시 오버헤드
    • 프로세스가 바뀌기 때문에 현재 CPU 캐시에 담긴 프로세스의 코드와 데이터를 무효화 시켜아 한다. 이 과정에서 캐시 속 수정된 데이터가 메모리에 복사되는 캐시 플러시 시간이 소요된다. 이 후 프로세스가 시작되면 CPU 캐시에 캐시 미스가 발생하고 캐시가 채워지는 과정이 진행되는데 캐시 미스와 캐시가 채워지는 시간은 컨텍스트 스위칭 시간에 포함시키지 않는다. 

5. 커널 레벨 스레드와 사용자 레벨 스레드

1) 정의를 각각 간단히 말하라.
  • 커널 레벨 스레드(kernel—level thread) - 커널에 의해 스케줄링되는 스레드
  • 사용자 레벨 스레드(user—level thread) — 스레드 라이브러리에 의해 스케줄링되는 스레드
2) 스레드로 실행을 시작할 함수는 사용자 영역에 있다. 이 함수가 커널 레벨 스레드로 실행 될 수 있는지 이유와 함께 설명하라.
  • 커널 레벨 스레드란, TCB가 커널에 의해 커널 공간에 만들어지고 커널에 의해 스케줄되는 스레드이다. 시스템 호출을 통해 스레드가 만들어지면, TCB는 커널 공간에 만들어진다. TCB에 저장된 스레드 코드의 주소는 응용 프로그램의 코드를 가르키고, 이 TCB가 커널 스케줄러에 의해 스케줄링 되면, CPU는 응용 프로그램에 작성된 사용자 코드를 실행한다. 이로써 커널 레벨 스레드를 통해 사용자 영역에 있는 스레드 코드를 실행할 수 있다.

6. 멀티스레드 구현에서

1) N:1 매핑은 멀티스레드 응용프로그램에서 만든 여러 스레드 중 한 개가 파일 입출력으로 인해 블록 상태가 되면 응용프로그램 내의 다른 모든 스레드가 스케줄되지(실행되지) 못하게 되는 문제점이 있다. 이 과정을 그림으로 그리고 간단히 설명하라.

n1mapping

2) 1:1 매핑이 오늘날 컴퓨터 시스템에서 많이 사용되는 이유가 무엇인지 설명하라.
  • 단점에도 불구하고, 1:1 매핑은 개념이 단순하여 구현하기 쉽고, 특히 멀티 코어 CPU에서 높 은 병렬성을 얻을 수 있어서 현재 리눅스를 포함한 대부분의 운영체제가 적용하고 있다

7. 교재의 복합 문제 1의 멀티스레드 응용프로그램을 작성하라. 프로그램 소스 코드와 실행 결과를 함께 보여라. 소스코드는 텍스트 형식으로 PDF에 삽입하라. 이 문제는 4개의 스레드 가 자신에게 맡겨진 덧셈 작업을 하여 그 결과를 sum[i]에 저장하고, main 스레드는 최종적 으로 sum[] 배열을 합쳐 출력하는 문제이다. 참고로, 문제에 언급한 runner() 함수는 4개의 스레드가 동시에 실행할 코드로 사용된다. 하지만 runner() 함수에 선언된 지역변수들은 모두 각 스레드의 스택에 독립적으로 생기기 때 문에 여러 스레드가 runner() 함수를 동시에 실행해도 문제가 되지 않는다. * 페이지 253의 상단 박스에서 스레드1,2,3,4를 다음과 같이 수정하세요. “스레드1:1~10000 까지의 합을 구하고 sum[0]에 저장“ -> “스레드1:1~10000 까지의 합을 바로 sum[0]에 합산”

  • 1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    
    #include<pthread.h>
    #include<stdio.h>
    #include<stdlib.h>
      
    int sum[4] = {0,};
    void * runner(void * param);
      
    int main(){
        char * values[4] = {"1","10001","20001","30001"};
        pthread_t tid[4];
        pthread_attr_t attr[4];
      
        for(int i = 0 ; i < 4 ; i ++){
            pthread_attr_init(&attr[i]);
            pthread_create(&tid[i],&attr[i],runner,values[i]);
        }
      
        for(int i = 0 ; i < 4 ; i ++)
            pthread_join(tid[i], NULL);
      
        int result = 0;
        for(int i = 0 ; i < 4 ; i ++)
            result += sum[i];
        printf("1에서 40,000까지 4개의 스레드가 계산한 총 합은 %d\n",result);
    }
      
    void * runner(void * param){
        int start = atoi(param);
        int idx = start / 10000;
        for(int i = start ; i < start + 10000 ; i++)
            sum[idx] += i;
    }
    

8-1

8. 교재의 복합 문제 2의 멀티스레드 응용프로그램을 작성하라. 프로그램 소스 코드와 실행 결과를 함께 보여라. 소스코드는 텍스트 형식으로 PDF에 삽입하라. 지시된 대로 코딩하여 실행시키면 실행 결과가 틀리게 나온다. 그 이유를 나름대로 설명하라. * 페이지 253의 하단 박스에서 스레드1,2,3,4를 다음과 같이 수정하세요. “스레드1:1~10000 까지의 합을 구하고 sum에 합산 pthread_create(…, runner, “1”); // 1에서 10000까지 합을 구하여 sum에 합산“ -> “스레드1:1~10000 까지의 합을 바로 sum에 합산” pthread_create(…, runner, “1”); // 1에서 10000까지 합을 바로 sum에 합산“ …

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include<pthread.h>
#include<stdio.h>
#include<stdlib.h>

int sum = 0;
void * runner(void * param);

int main(){
    char * values[4] = {"1","10001","20001","30001"};
    pthread_t tid[4];
    pthread_attr_t attr[4];

    for(int i = 0 ; i < 4 ; i ++){
        pthread_attr_init(&attr[i]);
        pthread_create(&tid[i],&attr[i],runner,values[i]);
    }

    for(int i = 0 ; i < 4 ; i ++)
        pthread_join(tid[i], NULL);

    printf("1에서 40,000까지 4개의 스레드가 계산한 총 합은 %d\n",sum);
}

void * runner(void * param){
    int start = atoi(param);
    for(int i = start ; i < start + 10000 ; i++)
        sum += i;
}

8-2

위 코드에서 4개의 스레드는 각각 자신에게 주어진 범위의 값(n ~ (n-1) + 10000)을 공유 데이터인 sum에 저장하려고 동시에 접근한다. 예를 들어 sum의 값이 0인 상황에서 첫 번째 스레드가 1을 저장하려는 상황에 두 번째 스레드가 10000을 저장하려고 할 때 첫 번째 스레드는 sum의 값이 0인 것을 확인하고 1을 저장하고 두 번째 스레드는 sum 값이 0임을 확인하고 10000을 저장하여 원하는 값인 10001이 아닌 다른 값이 저장된다. 따라서 이는 스레드 사이의 동기화 문제이다. 즉 여러 스레드가 공유 데이터에 동시에 접근하여 발생하는 문제이다.

This post is licensed under CC BY 4.0 by the author.