스레드( Thread ) 하드웨어 스레드
。소프트웨어 스레드:프로세스가 할당받은 자원을 이용하는 실행단위
▶CPU에서 실행하는 명령어 단위로 해석가능
。단일프로세스내에서 실행되는 명령어의 흐름
스레드프로세스
▶스레드는LWP( lightweight process )
▶스레드는프로세스의 특징을 공유하므로프로세스와 동일한상태(new,running,... ) 등을 가진다
。멀티스레드를 통해프로세스는 여러스레드를 가질 수 있으며 각스레드는 독립적으로 실행
프로세스내스레드구조
。프로세스내스레드들은 동일한Text Section / Data Section / Heap Section의프로세스 주기억장치 영역을 공유하며 각스레드들은 고유한스레드ID / Stack / 프로그램 카운터 / 레지스터 집합를 가진다.
▶멀티스레딩을 통해 동일한프로세스 자원을 공유하면서스레드별로독립적으로Concurrently하게함수를 실행 및 각스레드의실행위치및상태를 독립적으로 관리 가능
스레드ID( Thread ID ) :
。개별스레드의 식별을 위해 존재
프로그램 카운터( Program Counter ) :
。스레드가 다음에 실행할 명령어의 주소를 지시하는포인터
▶ 각스레드의 실행위치를 저장하기 위해 각스레드마다 별도로PC를 가진다.
레지스터 집합( Register Set ) :
。스레드가 현재 실행되는상태를 저장하는데 사용하는임시저장장치의 집합
▶ 각스레드의 명령어 처리중 값을 임시로 저장하기 위해 각스레드는 별도의레지스터 집합 공간을 가진다.
스택( Stack ) 프로세스 메모리 레이아웃 - 스택
。스레드에서의함수호출 시매개변수,되돌아갈 주소값,함수 내 지역 변수을 저장하는주기억장치 영역
▶ 각스레드마다 독립적인함수 호출을 위해 각스레드는 별도의스택 영역을 가진다.
스레드의 실행방식 종류
。하드코어 스레드,소프트웨어 스레드로 구분
▶하드코어 스레드:CPU의 단일코어가 동시에 처리하는 명령어 단위로서논리 프로세서
▶소프트웨어 스레드:OS의 단일 프로그램( =프로세서)에서 독립적으로 실행되는 단위
소프트웨어 스레드실행방식 종류
싱글 스레드( Single Thread ):
。단일프로세스가 하나의스레드만 가지면서 한번에 오직 한Task를 처리하는 것을 의미
멀티 스레드( Multi Thread )
。단일프로세스가 여러스레드들을 가지면서 동시에 여러Task를 처리하는 것을 의미
。OS이 제공하는멀티태스킹or멀티 프로세싱기능을 통해 수행됨
。예전에는병렬처리에 대해 여러코어들을 통한parallelism으로서 멀티코어 프로세서가 유행했다면 현재는OS를 이용한Concurrency의멀티 스레드가 유행
▶ ex.JAVA
스레드의 2가지TYPE
。생성 주체(사용자orOS)에 따라 구분
User Thread
。User Level Library에 의해 구현되어user mode에서스레딩하는스레드
▶JAVA등의 프로그래밍 언어의스레드 관련 라이브러리로 생성된스레드
。OS가 아닌라이브러리에 의해스레드 생성및스케줄링을 관리
▶Kernel이 직접 개입하지 못한다.
。동일메모리 영역에서스레드의 생성 및 관리가 되므로 속도가 빠름
。프로세스내User Thread중 특정User Thread가System Call에 의해 중단 시프로세스가 중단
▶Kernel입장에서는User Thread를 인식하지 못하므로System Call발생 시프로세스를waiting상태로 전환
Kernel Thread
。Kernel에 의해 구현되어kernel mode에서스레딩하는스레드
▶OS에 의해스레드 생성및 개별적으로스케줄링을 통해 관리됨
。User Thread에 비해스레드의 생성 및 관리속도가 느리다.
。프로세스내Kernel Thread중 특정Kernel Thread가System Call에 의해 중단이 되더라도 다른Kernel Thread는 영향 없이 계속 실행
▶멀티 코어환경에서도병렬 처리에 유리.Multi-Threading Model 종류
。User Thread와Kernel Thread간 관계를 의미
▶User Thread와Kernel Thread는 생성한프로세스에 대해 반드시 결합.
Many to OneModel
。여러User Thread가 단일Kernel Thread에Mapping
。스레드가User Level Library에 의해 관리되므로 속도가 빠르지만,스레드하나가System Call등에 의해 정지할 경우 나머지스레드들도 모두 정지
One to OneModel
。단일User Thread를 단일Kernel Thread로 각각Mapping
。한스레드가 중지되어도 다른스레드에 영향이 없지만 속도가 느려 효율이 좋지않음
▶Concurrency측면에서는Many-to-one에 비해 유리
Many to ManyModel
。M개의User Thread를N개의Kernel Thread로Mapping
。위 장점들을 모두 가지지만 구현이 어려움.
Thread Library
。스레드를 생성 및 관리하기위한API의 집합
ex )JAVA의Thread Class등
가장 많이 사용되는Thread Library종류
。POSIX Pthreads▶Linux계열에서 주로 사용
。Windows threads
。Java threads
Pthreads( Posix Thread )#include <pthread.h>
。UNIX OS에서멀티스레딩을 통한 병렬처리 프로그래밍을 위한API집합
▶커널 스레드정의
▶POSIX표준의Thread Library(IEEE 1003.1c)
▶병렬 프로그램은 여러스레드들을 통해 구동
。메인스레드에서 2개의커널스레드생성 시 서로Round Robin 스케쥴링으로Context Switching을 수행하면서Concurrent하게Task를 처리int main(){ pthread_t tid1, tid2; // 스레드 생성 pthread_create(&tid1, NULL, 사용자정의 함수, NULL); pthread_create(&tid2, NULL, 사용자정의 함수, NULL); // 각 스레드끼리 Context Switching 발생 시 비동기 작동 차단 pthread_join(tid1,NULL); pthread_join(tid2,NULL); printf("%d\n", sum); }。
메인스레드내 2개의커널스레드(tid1,tid2) 생성 후Context Switching을 하면서 특정함수를 실행
▶ 각스레드는parallel하게 실행되는게 아닌,Concurrent하게 실행
POSIX( Portable Operating System Interface For Unix )
。서로 다른UNIX OS간 호환성을 위해 공통API를 책정한Application Interface규격
▶POSIX를 준수하는UNIX OS는 다른UNIX OS와 호환
Java에서의User Thread
。Java는스레드기반으로 개발한 언어
▶자바로 구축한Application은 기본적으로스레드기반으로 실행하며메인 스레드에서main()를 실행하여 시작
。Java는멀티스레딩을 지원하며 여러 작업을Concurrently하게 실행
。여러종류의스레드 API를 지원
▶ 각스레드의 생성 및 관리가 쉽다
。단.JAVA는User Thread를 생성 및 관리
▶OS에 의해 관리되지 않으며JAVA에 의해스레드가 관리됨
▶JVM에 의해 특정OS의kernel thread(pthreads등 )와Many to One Model등의 관계를 맺어서 운용
。자바에서 스레드 활용
UNIX OS에서의Kernel Thread
。pthreads Library사용#include <stdio.h> #include <stdlib.h> #include <pthread.h> // 컴파일러 인식하기위해 전역변수 및 프로토타입 선언 int sum; // 전역변수 void *runner(void *param); // int main(int argc , char *argv[]){ pthread_t tid; // 스레드 식별 pthread_attr_t attr; // 스레드 속성 pthread_attr_init(&attr); pthread_create(&tid,&attr, runner, argv[1]); pthread_join(tid, NULL); printf("sum = %d\n", sum); } void *runner(void *param){ int i, upper = atoi(param); sum = 0; for(int i = 0 ; i <= upper ; i++){ sum += i; } pthread_exit(0); }。이때, 함수
void *runner(void *param)의 경우Java의Thread Class의public void run()과 같은 역할을 수행
▶pthread_create()에 의해 호출됨
。gcc -pthread 파일명.c를 통해 컴파일
스레드예제
- 다음 코드에서 생성되는
Unique한스레드와프로세스수는?pid_t pid; pid = fork(); if ( pid == 0 ){ // 자식프로세스 fork(); thread_create( .... ); } fork()。
스레드수 : 2개 /프로세스수 : 6개
- 예제2
#include <stdio.h> #include <stdlib.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; // 프로세스 ID pthread_t tid; // 스레드 ID pthread_attr_t attr; // 스레드 속성 pid = fork(); // 자식 프로세스 생성 if (pid == 0){ // 자식프로세스 pthread_attr_init(&attr); pthread_create(&tid,&attr, runner, argv[1]); pthread_join(tid, NULL); printf("CHILD : value = %d\n" , value); } else if ( pid > 0 ){ // 부모프로세스 wait(NULL); printf("PARENT : value = %d\n" , value); } } void *runner(void *param){ value = 5; pthread_exit(0); }
퀴즈문제 해설
출처
。운영체제 공룡책 강의