400 likes | 963 Views
4 장 : 다중 쓰레드 프로그래밍. 4 장 : 다중 쓰레드 프로그래밍. 개요 다중 쓰레딩 모델 (Multithreading Models) 쓰레딩 주요 사항들 (Threading Issues) Pthreads 윈도우 쓰레드 ( Windows Threads) 리눅스 쓰레드 ( Linux Threads) 자바 쓰레드 ( Java Threads). 쓰레드란 ?. 프로세스 내의 제어 흐름 이다 ( a flow of control within a process )
E N D
4장: 다중 쓰레드 프로그래밍 • 개요 • 다중 쓰레딩 모델(Multithreading Models) • 쓰레딩 주요 사항들 (Threading Issues) • Pthreads • 윈도우 쓰레드(Windows Threads) • 리눅스 쓰레드(Linux Threads) • 자바 쓰레드(Java Threads)
쓰레드란? • 프로세스 내의 제어 흐름이다(a flow of control within a process) • 단일 쓰레드 프로세스, 다중 쓰레드 프로세스 • CPU 이용의 기본 단위로서 아래 정보들로 이루어진다 • 쓰레드 ID, 프로그램카운터, 레지스터 집합, 스택 • 같은 프로세스 내에 속한 다른 쓰레드들과 코드 영역, 데이터 영역, 운영체제의 다른 자원들(개방 파일, 신호)을 공유한다 • 하나의 프로세스가 제어의 다중 쓰레드를 가진다면, 그 프로세스는 하나 이상의 작업을 동시에 수행할 수 있다
다중 쓰레드 프로그램 • 현대 운영체제에서 수행되는 많은 소프트웨어 패키지들은 다중 쓰레드를 지원한다 • 웹 브라우저는 다음과 같이 이루어져야 한다 • 이미지나 텍스트를 전시하는 쓰레드 1개 • 네트워크로부터 데이터를 가져오는 또 다른 쓰레드 1개 • 워드 프로세서는 다음과 같이 이루어질 수 있다 • 그래프를 전시하는 쓰레드 1개 • 사용자의 키 스트로크에 응답하는 또 다른 쓰레드 1개 • 스펠링과 문법 검사를 수행하는 세 번째 쓰레드
멀티 쓰레드 프로그램 • 웹 서버 • 단일 쓰레드 웹 서버: 한 클라이언트는 요청에 대한 서비스가 완료될 때 까지 기다려야 한다 • 다중 프로세스 웹 서버: 쓰레드가 일반적이기 전에 사용되었다. 새로운 프로세스를 생성하는데 많은 오버헤드가 발생한다 • 다중 쓰레드 웹 서버: 쓰레드 생성에 적은 오버헤드, 다중 클라이언트에 대한 동시 서비스 • 많은 운영체제 커널들이 현재 다중 쓰레드 기반이다 • 여러 쓰레드들이 커널 내에서 동작한다 • 각 쓰레드는 장치를 관리하거나 인터럽트를 처리하는 등의 특정 작업을 수행한다
다중 쓰레드 프로그램의 장점 • 반응성(Responsiveness) • 상호작용하는 응용의 다중쓰레딩은 하나의 프로그램이 차단되어도 수행을 계속하게 하거나 긴 연산을 수행하도록 한다 • 자원공유(Resource Sharing) • 쓰레드는 프로세스에게 소유된 메모리와 자원을 공유한다 • 경제성(Economy) • 하나의 프로세스 내의 쓰레드는 자원을 공유하기 때문에, 쓰레드 생성과 내용-전환(context-switch)을 수행함에 있어 더 경제적이다 • 솔라리스에서 프로세스를 생성하는 것이 쓰레드를 생성하는 것보다 약 30배 정도 더 느리다 • 다중 프로세서 구조의 활용 • 쓰레드는 서로 다른 프로세서에서 병렬로 실행될 수 있다
쓰레드의 두 가지 유형 • 사용자 쓰레드(User Thread) • 커널 쓰레드(Kernel Thread) • 사용자 레벨 쓰레드는 프로그래머에게는 보이고,커널에게는 알려지지 않은쓰레드들이다 • 운영체제 커널은 커널 레벨 쓰레드를 지원하고 관리한다 • 일반적으로 사용자 레벨 쓰레드들은 커널 쓰레드들보다 더 빨리 생성하고 관리할 수 있다. 왜냐하면 커널의 개입이 필요하지 않기 때문이다
사용자 쓰레드(User Threads) • 쓰레드 관리는 사용자 레벨 쓰레드 라이브러리에 의해 이루어진다 • 사용자 쓰레드는 커널 위(above)에서 지원되나, 커널의 지원 없이 관리된다 • 세 가지 기본 쓰레드 라이브러리 : • POSIX Pthreads • Win32쓰레드 • Java쓰레드
커널 쓰레드(Kernel Threads) • 커널에 의해 지원 받는다 • 쓰레드는 운영체제에 의해 직접 지원받고 관리된다 • 예제 • 윈도우 XP/2000 • 솔라리스 • 리눅스 • Tru64 유닉스 • 맥 OS X
다중 쓰레딩 모델 • 사용자 쓰레드들과 커널 쓰레드들 사이의 관계 • 다-대-일(Many-to-One) • 일-대-일(One-to-One) • 다-대-다(Many-to-Many)
다-대-일(Many-to-One) • 많은 사용자 쓰레드들이 하나의 커널 쓰레드에매핑된다 • 쓰레드 관리는 사용자 공간의 쓰레드 라이브러리에 의해 이루어진다 • 사용자가 원하는 만큼의 많은 사용자 쓰레드를 생성할 수 있으므로 효율적이다 • 하나의 쓰레드가 봉쇄형(blocking) 시스템 호출을 할 경우, 전체 프로세스가 봉쇄된다 • 한 번에 하나의 쓰레드만이 커널에 접근할 수 있기 때문에, 다중 쓰레드가다중 프로세서에서 돌아도병렬로 작동할 수 없다 • 예제: • 솔라리스 쓰레드라이브러리 (green thread) • GNU Portable 쓰레드
일-대-일 • 각 사용자 레벨 쓰레드는 커널 쓰레드와 매핑된다 • 다-대-일 모델보다 더 많은병렬성을 제공한다 • 하나의 쓰레드가 차단 시스템 호출을 부르면, 또 다른 쓰레드가 수행되도록 한다 • 사용자 쓰레드를 생성하는 것은 그에 대응하는 커널 쓰레드를 생성하는 것을 필요로 한다 – 오버헤드 • 하나의 프로세스가 생성할 수 있는 쓰레드의 수는 다 대 일 모델보다 더 적다 – 너무 많은 쓰레드를 생성하지 않도록 주의해야 한다 • 예제 • 윈도우 NT/XP/2000 • 리눅스 • 솔라리스 9과 그 이후 버전
다-대-다 모델 • 많은 사용자 레벨 쓰레드는 그와 같거나 그 보다 더 적은 수의 커널 쓰레드와 매핑되게 된다 • 운영체제가 충분한 수의 커널 쓰레드를 생성하도록 한다 • 커널 쓰레드의 수는 응용이나 기계에따라결정된다 • 예제 • 솔라리스 9 이전 버전 • ThreadFiber패키지를 가진 윈도우 NT/2000
두 단계 모델 • 다-대-다 모델의 한 가지 대중적인 변화 • 다-대-다 모델과 유사함, • 많은 사용자 레벨 쓰레드를 같은 수나 더 적은 수의 커널 쓰레드로 다중화시킨다 • 그러나 하나의 사용자 쓰레드는 하나의 커널 쓰레드에 종속되도록 허용한다 • 예제 • IRIX • HP-UX • Tru64 유닉스 • 솔라리스 8과 그 이전 버전들
이 매핑은 어떤 모델인가? User Threads Kernel Threads
쓰레드 라이브러리들 • 쓰레드 라이브러리는 프로그래머에게 쓰레드를 생성하고 관리하기 위한 API를 제공한다 • 구현의 두 가지 기본적인 방법 • 라이브러리를 커널의 지원없이 사용자 공간에서 전부 제공한다 • 라이브러리를 위한 모든 코드와 데이트 구조는 사용자 공간에 존재한다 • 모든 함수 호출은 커널 모드가 아닌 사용자 모드에서 실행된다 • 운영체제에 의해 지원 받는 커널 레벨 라이브러리를 구현한다 • 모든 코드와 데이터 구조는 커널 공간에 존재한다 • 함수 호출은 커널의 시스템 호출을 야기한다 • 세 가지 주요 쓰레드 라이브러리들 • POSIX Pthreads - 솔라리스, 리눅스, 맥 OS X, Tru64 유닉스 • Win32쓰레드 - 윈도우 • Java쓰레드 - 자바
경량 프로세스 (Light Weight Processes: LWP) • 다-대-다또는 두 단계 모델을 구현한 많은 시스템들은 사용자와커널쓰레드 사이에 중간형태의 데이터 구조를 둔다 • 이 데이터 구조가 경량 프로세스라고 알려진 것이다 • 하나의 사용자 쓰레드는 하나의 LWP에 부속된다 • 각 LWP는 하나의 커널 쓰레드에 부속된다 • 운영체제는 CPU에서 수행되기 위해 프로세스가 아닌 커널 쓰레드를 스케줄링 한다 • 커널 쓰레드가 봉쇄되면, LWP도 봉쇄되고, 사용자 쓰레드도 봉쇄된다 • 사용자 쓰레드 라이브러리에게, LWP는 응용 프로그램이 사용자 쓰레드가 수행되도록 스케줄링할 수 있는 가상 CPU처럼 보인다 • 사용자 쓰레드 라이브러리는 LWP에 대한 사용자 쓰레드 사이에서스케줄링을 책임져야 한다. 이것은 커널의 CPU 스케줄링과 유사하다 • 일반적으로, 사용자 쓰레드 사이에서 내용 전환은 LWP의 사용자 쓰레드를 취하고 그것을 다른 쓰레드로 교환하는 것을 포함한다
쓰레딩의 주요 사항들 • fork()와 exec() 시스템 호출 • 쓰레드취소(cancellation) • 시그널 처리(signal handling) • 쓰레드 풀(pool) • 쓰레드별 데이터(thread-specific data) • 스케줄러 활성화
fork()와 exec() 시스템 호출 • fork()시스템 호출은 별도의 복제된 프로세스를 생성하는데 사용된다 • 만약 한 프로그램의 쓰레드가 fork()를호출하면, • 새로운 프로세스는 모든 쓰레드를 복제해야 하는가? • 아니면 한 개의 쓰레드만 가지는 프로세스여야 하는가? • 몇몇 유닉스 기종은 이 두 가지 버전 fork()를 다 제공한다
쓰레드 취소(Cancellation) • 쓰레드가 끝나기 전에 다른 쓰레드에 의해 종료되는것을 일컫는다 • 예: 여러 쓰레드가 데이터베이스를 병렬로 검색하고 있다가 그 중 한 쓰레드가 결과를 찾았다면 나머지 쓰레드들은 취소된다 • 목적 쓰레드(target thread)를 취소하는 두 가지 일반적인 방법 • 비동기 취소(Asynchronous cancellation)는 한 쓰레드가 즉시 목적 쓰레드를 강제 종료시킨다 • 지연 취소(Deferred cancellation)는 목적 쓰레드가 주기적으로 자신이 강제 종료되어야 할지를 점검한다. 이 경우 목적 쓰레드가 질서 정연하게 강제 종료될 수 있는 기회가 만들어진다
쓰레드 취소 • 비동기화 취소(Asynchronous cancellation) • 쓰레드 취소의 어려움은 상황에 따라 발생한다 • 자원이 취소된 쓰레드에게 할당되어 있거나, • 다른 쓰레드와 자원을 공유하고 있는 쓰레드가 데이터를 갱신하고 있는 도중에 취소 요청이 와도 문제가 된다 • 지연 취소(Deferred cancellation) • 한 쓰레드가 목적 쓰레드가취소 예정이라고 표시한다 • 취소는 목적 쓰레드가 취소 여부를 결정하기 위하여 플래그를 검사한 이후에야 일어난다
신호 처리 • 신호는유닉스에서프로세스에게어떤 사건이 일어났음을알려주기 위해 사용된다 • 신호의 두 가지 유형 • 동기화 신호(Synchronous signals) • 불법적인 메모리 접근, 0으로 나누기 • 비동기화 신호(Asynchronous signals) • 특수기를 누르는 것(Ctrl-C), 타이머 만료 • 신호가 발생하면 어떤 일이 생기는가? • 신호는 특정 사건이 일어나야 발생한다 • 신호가 생성되면 커널로부터 프로세스에게 전달된다 • 신호가 전달되면 반드시 처리되어야 한다
신호 처리 • 모든 신호는 둘 중 하나의 처리기에의해 처리된다 • 디폴트 신호 처리기 • 사용자 정의 신호 처리기 • 모든 신호마다 커널에 의해 실행되는 디폴트 신호 처리기가 있다 • 이 디폴트 처리기는 신호를 처리하기 위해 호출되는 사용자 정의 신호 처리기에 의해 대체될 수 있다 • 다중 쓰레드 프로세스에서 신호처리는 더욱 복잡하다. 신호를 전달함에 있어 다음과 같은 선택이 존재한다 • 신호가 적용될 쓰레드에게 전달한다 • 프로세스 내의 모든 쓰레드에게 전달한다 • 프로세스 내의 몇몇 쓰레드들에게만 선택적으로 전달한다 • 특정 쓰레드가 모든 신호를 전달받도록 지정한다
쓰레드 풀(Thread Pools) • 쓰레드가 작업을 기다리는 쓰레드 풀 • 프로세스는 시작시에 일정 수의 쓰레드를 생성하여 쓰레드 풀에 놓는다 • 요청을 받으면, 서버는 풀로부터 쓰레드를 깨워서 요청을 서비스에게 전달한다 • 쓰레드가 서비스를 끝내면, 다시 풀로 반환되고 다음 작업을 기다린다 • 만약 풀이 더 이상 가용 쓰레드를 포함하고 있지 않으면, 서버는 하나의 풀이 자유로워 질때까지 기다린다 • 장점: • 보통 존재하는 쓰레드에 요청하는 것이 새로운 쓰레드를 생성하는 것보다 서비스를 약간 더 빨리 받을 있다 • 응용 프로그램에서 쓰레드의 수는 풀의 사이즈에 종속되게 한다
쓰레드 별 데이터 • 프로세스에 속한 쓰레드는프로세스와 데이터를 공유한다 • 어떤 상황에서, 각 쓰레드는 자기 자신만의 데이터가 필요할 수도 있다 • 각 쓰레드는 자기 자신만의 데이터 복사본을 갖도록 한다 • 쓰레드 생성 과정에 대한 제어권이 없을 때 유용하다 (예, 쓰레드 풀을 사용할 때) • 대부분 쓰레드 라이브러리(Win32, Pthread, Java)는쓰레드 별 데이터를 지원하기 위한 형식을 제공한다
스케줄러 활성화 • 다-대-다 모델과 두 단계 모델 모두 응용에 할당된 커널 쓰레드의 수를 적당히 유지하기 위한 통신을 필요로 한다 • 스케줄러 활성화는upcalls을 제공한다,upcalls은커널에서부터 쓰레드 라이브러리로 통신하는 방법이다 • 이 통신은 응용 프로그램이 올바른 커널 쓰레드의 수를 유지하는 것을 가능케 한다
Pthreads • 쓰레드 생성과 동기화를 위한 POSIX표준 (IEEE 1003.1c) API • API는 쓰레드 라이브러리의 행동을 명세한다 • 구현은 라이브러리 개발에달려 있다 • 유닉스 운영 체제 시스템에서 일반적 (솔라리스, 리눅스, 맥 OS X)
윈도우 XP 쓰레드 • 일-대-일 매핑으로 구현된다 • 각 쓰레드는 아래 정보를 포함한다 • 하나의 쓰레드 id • 레지스터 집합 • 개별 사용자/커널 스택들 • 개인 데이터 저장 구역 • 레지스터 집합, 스택, 개인 저장 구역은 쓰레드의 내용(context)라고 알려졌다 • 쓰레드의 기본 데이터 구조는 다음을 포함한다: • ETHREAD (운영 쓰레드 블록) • KTHREAD (커널 쓰레드 블록) • TEB (thread environment block: 쓰레드 환경 블록)
리눅스 쓰레드 • 리눅스는 쓰레드(threads)라기 보다는 작업(tasks)으로 간주한다 • 쓰레드생성은 clone()시스템 호출에 의해 이루어진다 • clone()은 자식 작업이 부모 작업(프로세스)와 주소 공간을 공유하는 것을 가능케 한다
자바 쓰레드 • 자바 쓰레드는 JVM(Java Virtual Machine: 자바가상 기계)에 의해 관리된다 • 자바 쓰레드는 다음에 의해 생성될 수 있다: • 쓰레드 클래스 확장(Extending Thread class) • 실행 가능한 인터페이스 구현(Implementing the Runnable interface) • JVM은 주인 운영체제(host OS) 상에서 실행되기 때문에, 자바 쓰레드 API는 전형적으로 주인 시스템에서 실행가능한 쓰레드 라이브러리를 사용하여 구현된다 • 윈도우 시스템: Win32쓰레드 라이브러리를 사용하여 • 리눅스, 유닉스 시스템: Pthread라이브러리를 사용하여
요약 • 쓰레드는 프로세스 내의 제어 흐름이다 • 다중 쓰레드 프로세스는 같은 주소 공간 내에 여러 다른 제어 흐름을 포함한다 • 다중 쓰레딩의 장점 • 향상된 반응성, 프로세스 내의 자원 공유 • 경제성, 다중 프로세서 구조를 이용할 수 있는 가능성 • 사용자 레벨 쓰레드는 프로그래머에게는 보이고, 커널에게는 알려지지 않은 쓰레드 이다 • 운영체제 커널은 커널 레벨 쓰레드를 지원하고 관리한다 • 사용자 쓰레드와 커널 쓰레드 관계의 세가지 유형의 모델 • 일-대-일(One-to-one),다-대-일(many-to-one),다-대-다(many-to-many) • 쓰레드라이브러리는 응용 프로그래머에게 쓰레드를 생성하고 관리하는 API를 제공한다 • POSIX Pthreads, Win32쓰레드, Java쓰레드 • 다중 쓰레드 프로그램은 다음과 같은 여러 주요 고려사항들을 포함한다 • fork()/exec(), 쓰레드 취소, 신호 처리, 쓰레드 풀, 쓰레드 별 데이터