멀티쓰레딩

Timo·2022년 7월 22일
0
post-thumbnail

08. 멀티쓰레딩

#운영체제 #study

Chapter 4. Thread & Concurrency (Part 2)

4.3 Multithreading Models

Two types of threads

  • user threads
    커널의 지원 없이, 커널 위 계층인 사용자 모드에서 관리되는 스레드
    운영체제와는 무관한, 어플리케이션 레이어에서의 스레드 환경? Ex. 자바의 스레드
  • kernel threads
    커널 모드에서 사용하는 스레드
    운영체제가 직접 관리하는 스레드

Three relationships between user and kernel threads

Many-to-One Model

  • 커널 스레드 하나가 여러 개의 유저 스레드를 관리하는 형태
  • 가장 기본적으로 사용하는 형태?

One-to-One Model

  • 하나의 커널 스레드가 하나의 유저 스레드만 관리하는 형태

Many-to-Many Model

  • 여러 개의 유저 스레드를 한정된 커널 스레드 안에서 서로 매핑시켜서 처리하고 나면 반납하는 것을 반복하는 형태

4.4 Thread Library

Three main thread libraries are in use today

  • POSIX Pthreads
  • Windows thread
  • Java thread

Pthreads

  • 리눅스, 유닉스 계열에서 사용하는 스레드 라이브러리

Figure 4.11/Multithreaded C program using the Pthread API./

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

/* the data shared by the threads */
int sum;/* thread call this function */ 
void * runner(void *param); 

int main(int argc, char *argv[])
{
	pthread_t tid;          // thread identifier
	pthread_attr_t attr;    // thread attributes
                                     
	pthread_attr_init(&attr);
	
	//Java의 new Thread와 동일pthread_create(&tid, &attr, runner, argv[1]); 
	
	//위 스레드가 종료될 때까지 대기하다가 이어서 진행한다.
	pthread_join(tid, NULL);

	printf("sum = %d\n", sum);
} 


//Java의 public vod run() 메서드와 동일, *param으로 argv[1] 전달
void * runner(void *param) 
{
	int i, upper = atoi(param); 
	sum = 0;

	//1~N까지 합 구하는 로직for (i = 0; i <= upper; i++) 
		sum += i;
	
	//스레드 종료 명령어?
	pthread_exit(0);
} 

Exercise 4.19 (p. 910)

#include <stdio.h> 
#include <unistd.h> 
#include <wait.h> 
#include <pthread.h> 

//전역 변수
int value = 0;
void * runner(void *param);

int main(int argc, char *argv[])
{
	pid_t pid; 
	pthread_t tid; 
	pthread_attr_t attr; 

	pid = fork(); //프로세스 생성

	if (pid == 0) { // child process 
		pthread_attr_init(&attr); 		

		pthread_create(&tid, &attr, runner, NULL);

		pthread_join(tid, NULL); 

		printf("CHILD: value = %d\n", value); // LINE C
	}
	else if (pid > 0) { // parent process 
		wait(NULL); 
		printf("PARENT: value = %d\n", value); // LINE P
	}
} 

void *runner(void *param) 
{ 
	value = 5; 
	pthread_exit(0);
}

출력 결과

CHILD: value = 5
PARENT: value = 0

-> 프로세스 내에서 전역 변수는 스레드 사이에 공유된다.

4.5 Implicit Threading - 암시적 스레딩

The Strategy of Implicit Threading

  • Thread Pools
  • Fork & Join
  • OpenMP
  • Grand Central Dispatch(GCD)

OpenMP

  • 컴파일러에게 병렬로 수행해야 하는 곳을 알려주면 컴파일러가 알아서 스레드를 관리해주는 것

사용법(병렬 수행 블록 지정)

#include <stdio.h> 
#include <omp.h> 
int main(int argc, char *argv[])
{
	#pragma omp parallel // compiler directive
	{
		//이 블록 안의 코드는 병렬로 수행한다.
		printf("I am a parallel region.\n");
	}
	return 0; 
} 

사용법(스레드 갯수 지정)

#include <stdio.h>
#include <omp.h>
int main(int argc, char *argv[])
{
	//스레드 갯수 지정
	omp_set_num_threads(4);
	#pragma omp parallel 
	{ 
		//스레드 번호 조회
		printf("OpenMP thread: %d\n", omp_get_thread_num()); 
	} 

	return 0; 
} 

출력 결과

OpenMP thread: 3
OpenMP thread: 0
OpenMP thread: 2
OpenMP thread: 1

병렬 수행 예시 코드

#include <stdio.h>
#include <omp.h>

#define SIZE 100000000

int a[SIZE], b[SIZE], c[SIZE]; 

int main(int argc, char *argv[]) 
{ 
    int i;
    for (i = 0; i < SIZE; i++)
        a[i] = b[i] = i;

    #pragma omp parallel for
    for (i = 0; i < SIZE; i++) {
        c[i] = a[i] + b[i];
    }
	  return 0; 
} 

수행 시간

real 0m0.586s
user 0m0.364s
sys 0m0.223s

real 0m0.423s 
user 0m1.091s 
sys 0m0.441s 
profile
나는 매일 성장하는 사람

0개의 댓글