23.07.07 최초 작성
프로그램에서 하나의 실행 상태를 나타내는 단위. 하나의 프로세스에 여러 스레드가 존재 가능하며 이 스레드들은 코드, 전역변수, 힙 영역, 열려있는 파일 등 프로세스의 메모리 영역을 공유한다. 하지만 레지스터, PC, SP를 공유하지 않는다.
cpu에 실행시킬 프로그램을 결정하는 스케줄링의 단위이다.
Single-threaded process
하나의 프로그램에 쓰레드가 1개 존재하는 형태 (context가 1개)
Multi-threaded process
하나의 프로그램에 쓰레드가 2개 이상 존재하는 형태(context가 여러개)
장점
- 멀티코어 구조를 온전히 활용 가능하다.
- 프로그램간의 자원의 공유가 명확해진다.
- 프로그램 구조를 향상시킬 수 있다.
- 스루풋과 반응성이 좋다.
Concurrency
여러개의 작업이 조금씩 동시에 진행할 수 있는 시스템의 성질
Parallelism
기계적(하드웨어적)으로 동시에 여러 작업을 동시에 실행할 수 있는 시스템의 성질
Data Parallelism
다른 코어에 각 데이터를 나눠 같은 작업을 진행하는 형태
Task Parallelism
각 다른 작업을 다른 코어에 나눠 작업하는 형태
추가적인 자원을 할당했을 때 처리속도의 향상되는 정도를 수식으로 나타낸 것
S | P | N |
---|---|---|
단일 처리 하는 부분 | 병렬 처리 하는 부분 | 코어 갯수 |
사용자가 API로 스레드를 생성하고 관리할 수 있도록 하는 라이브러리
#include<stdio.h>
#include<pthread.h>
int values[4] = {0,1,2,3};
void *hello(void * arg)
{
printf("hello, world\n");
}
int main()
{
pthread_t tid;
pthread_create(&tid, NULL, hello, NULL);
printf("hello from main thread\n");
}
int pthread_create (pthread_t *tid, pthread_attr_t *attr,
void*(start_routine)(void*), void *arg);
void pthread_exit (void *retval);
int pthread_join (pthread_t tid, void **thread_return);
라이브러리로 제공되기 때문에 컴파일 시 링크 해줘야 함
스레드의 생성과 관리 책임을 개발자가 하는것이 아닌 컴파일러와 런타임 라이브러리에게 넘겨주는 것
스레드를 일정 수 대기상태로 두고 스레드 생성 요청을 받으면 이 스레드 중 하나에게 작업을 할당한다. 작업이 종료되면 다시 스레드를 대기상태로 되돌린다.
스레드의 최대 갯수는 풀의 크기에 의해 제한되며 스레드를 생성할 필요가 없기 때문에 실행속도가 약간 더 빠르다.
메인 부모 스레드가 하나 이상의 자식 스레드를 fork한 다음 자식의 종료를 기다린 후 join하고 그 시점 부터 자식의 결과를 확인하고 결합하는 방법. Divede & Conquer 기법을 이용할 때 유용함.
컴파일 과정에서 컴파일러가 멀티스레딩을 공유할 수 있도록 하는 방법. 공유 메모리 환경에서 병렬 실행을 가능하게 한다.
#include <omp.h>
#include <stdio.h>
int a[4] = {0,1,2,3};
int b[4] = {0,1,2,3};
int c[4] ;
int main(){
// 병렬 영역 선언
#pragma omp parallel for
for (int i = 0; i < 4; i ++){
c[i] = a[i] + b[i];
}
#pragma omp parallel
{
printf("I am a parallel region");
}
return 0;
}
fork() 호출 시 새로운 프로세스는 특정 스레드만 복제하는 방법과 모든 스레드를 복제하는 방법을 모두 제공한다.
pthread 환경에서는 특정 스레드만을 복제하지만 UNIX 환경에서는 모든 스레드를 복제하는 fork(), 특정 스레드만을 복제하는 fork1()을 지원한다.
exec()의 경우 호출 시 프로세스와 프로세스의 모든 스레드를 초기화한다.
받은(인바운드) 시그널에 대해 어떤 스레드가 신호를 처리할 지 정해야 한다.
스레드가 작업을 완료하기 전 스레드를 종료시키는 작업
ptherad_cancel
스레드가 다른 스레드와 공유하지 않고 자신만 접근할 수 있는 데이터. 함수가 호출되는 동안 존재하는 지역변수와 다르게 스레드 전체에 걸쳐 존재한다.
__thread int TLS_var=0; //TLS 선언
리눅스에서 스레드는 'task'라고 하며 task_struct를 통해 스레드처럼 가상화된다. clone()이란 시스템 콜로 생성된다.