230 likes | 435 Views
5장 스레드 ( Threads). 프로세스 = 자원 + PC 스레드 : 새 PC (a thread of control) 로 같은 address space 를 실행하는 fork 와 유사. 경량 프로세스( LWP; lightweight process) = 스레드 CPU 를 이용하는 기본 단위 thread ID, PC, 레지스터 세트, 스택 영역을 가짐
E N D
5장 스레드 (Threads) • 프로세스 = 자원 + PC • 스레드: 새 PC (a thread of control)로 같은 address space를 실행하는 fork와 유사 • 경량 프로세스(LWP; lightweight process) = 스레드 • CPU를 이용하는 기본 단위 • thread ID, PC, 레지스터 세트, 스택 영역을 가짐 • 스레드들은 서로 같은 프로세스의 code section, data section, OS resources-open files, signals를 공유 (그림 5.1) • (예1) web browser • image와 text를 display하는 thread • network에서 데이터를 가져오는 thread • (예2) word processor • graphics를 display하는 thread • keystrokes를 읽어오는 thread • spelling과 grammar를 검사하는 thread • 중량 프로세스(heavyweight process) = 1 thread를 가진 task • 비교 • 경량 프로세스의 문맥교환 : CPU switching, thread context switch • 레지스터 세트 교환만 • 중량 프로세스의 문맥교환 : process switching, context switching • 레지스터 세트교환과 메모리 관련 작업도(virtual memory page table 변경 등) 스레드 (Threads) 개요 ~ 2000 운영체제
Single and Multithreaded Processes 2000 운영체제
스레드(Threads) 개요 ~ • 제어 • 다중 스레드 제어(multiple-thread control) • 자신의 PC, stack, 비독립적(no protection) • 다중 프로세스 제어(multiple-process control) • 자신의 PC, stack, address space, 독립적(protection) • 스레드의 특성 • CPU공유 • 준비, 수행, 대기상태 • 자식 thread생성 • block • (예1) 웹 서버 구현 • a single process : client의 대기시간이 매우 기어짐 • multiple process : client의 요청이 올 때마다 새 process 생성, overhead • multithreaded single process : 서버는 thread 생성하여 client의 요청 기다리다 요청이 오면 새 thread 생성하여 서비스, 효율적 • (예2) 생산자 소비자 문제 • 2 threads 로 구현하면 좋음(better if on 2 processors) 2000 운영체제
스레드(Threads) 개요 • Java의 thread 이용 • Java에는 비동기적 동작(asynchronous behavior) 없음 • (예) Java로 telnet 구현 • telnet하는 클라이언트는 서버와 연결되거나 timeout될 때까지 block 되어야 함 • timeout은 asynchronous event • Java로 구현하려면 2개 thread 생성 • telnet thread: 계속 서버에 연결 시도 • timer thread:timeout 시간동안 wait하다 깨어나 telnet thread가 아직도 연결 시도 중이면 interrupt 발생하여 중지시킴 • Thread의 장점 • 빠른 응답(responsiveness) • 자원 공유(resource sharing) • 경제적(economy) • 다중 프로세서 구조 이용(utilization of multiprocessor architecture) 2000 운영체제
사용자 스레드와 커널 스레드 (User and kernel Threads) • 사용자 스레드 (user threads) : Posix Pthreads, Mach C-threads, Solaris Threads • user level의 thread library로 구현: 라이브러리가 thread생성, 스케줄링, 관리 담당 • 불공평한 스케줄링(unfair scheduling) • 스위칭이 빠름(switching is fast) • single thread인 kernel에서 사용자 수준 스레드가 blocking system call을 수행할 경우 system call 완료까지 다른 모든 스레드들은 대기해야 함 • 커널 스레드 (kernel threads) : Windows NT, Solaris, Digital Unix • 커널이 thread생성, 스케줄링, 관리 담당 • 공평한 스케줄링(fair scheduling) • 스위칭 시간이 김(switching is time consuming) : interrupt 처리 때문 • blocking system call 수행시 커널이 다른 thread 실행 시킬 수 있음 • 혼합 접근 (hybrid approach) : Solaris 2 • kernel 자체 (system call 수행 방법) • single tasking : 초기 Unix kernel : 공유 자료 접근 동기화 불필요 • multi tasking • 동기적인 시스템 • Mach kernel : 스레드들은 동기적임(threads are synchronous), 다른 스레드가 제어를 넘겨준 다음에만 수행 가능(공유 데이타 변경 중에는 제어를 넘겨주지 않음) • 비동기적인 시스템 : 잠금 기법(locking mechanism)필요 2000 운영체제
다중 스레드 모델 (Multithreading Models) • Many-to-One Model : 초기 Solaris • 다수의 user-level thread가 하나의 kernel thread로 매핑 • 한 thread가 blocking system call하면 전체 프로세스 block • One-to-One Model : Windows NT, OS/2 • 각 user-level thread 가 하나의 a kernel thread로 매핑 • 한 thread가 blocking system call 해도 다른 thread 실행 가능 • User thread 생성마다 kernel thread 생성해야 함 • 동시성이 좋음(more concurrency): multiprocessors에서 병렬 처리(parallel processing) 가능 • Many-to-Many Model : Solaris 2.6, IRIX, Digital Unix • 다수의 user-level thread들이 더 적거나 같은 수의 kernel threads들로 매핑(multiplexed) • 동시성이 덜 좋음(less concurrency): 커널은 한 순간에 하나의 kernel thread만 스케줄 2000 운영체제
Many-to-one Model 2000 운영체제
One-to-one Model 2000 운영체제
Many-to-many Model 2000 운영체제
Solaris 2 Threads ~ • 솔라리스(Solaris) 2.x • SunOS Release 4.x - Solaris 1.x • SunOS Release 5.x - Solaris 2.x • Solaris 2의 지원 기능 • kernel수준과 user수준에서 스레드 지원 • symmetric multiprocessing(대칭적 다중 프로세싱) • 각 process가 OS가짐 Master-slave의 반대 • real-time scheduling(실시간 스케줄링) • 스레드들 : LWP(Light Weight Processes) = a virtual CPU • user-level (thread API들의 library) • thread ID, register set(PC, stack pointer), stack, 우선순위 • switching(linking with thread)이 빠르다. 문맥 교환 없음 • 종류 • bound: LWP에 영원히 연결됨, quick response 가능 • unbound: LWP 풀에 multiplexed • intermediate-level = LWP • kernel 자료구조, user level thread의 register set, 메모리와 계정정보 • 비교적 느리다. • kernel-level(CPU 스케줄링 대상) • 약간의 자료구조: stack, kernel registers, LWP pointer, 우선순위, 스케줄링 정보 • switching이 비교적 빠르다. 2000 운영체제
Solaris 2 Threads • 그림 5.5 Solaris 2의 스레드 • Many LWP, many CPU • N user-level thread <-> l LWP • 1 LWP <-> 1 Kernel-level thread = 1 system call • N Kernel-level thread <-> 1 CPU • (예) 동시에 5개 화일 읽기 -> 5 LWP필요 • 각 화일 읽기는 Kernel 안에서 I/O완료를 기다려야 함 • Solaris 2에서 • 한 task는 한 I/O완료를 기다리는 동안 block될 필요가 없음 : 어떤 작업의 한 LWP(kernel thread)가 I/O 완료를 기다리게 되더라도 CPU는 그 작업의 다른 LWP(kernel thread)로 이동하여 작업 수행을 계속 • thread library가 최적의 성능을 지원하도록 동적으로 LWP의 수 조절 • 실행 가능 LWP 한 개 남으면 새 LWP 생성 • 일정 기간(예, 5분)사용되지 않은 LWP 삭제 • 참조 • Solaris 2.x : System Administrator’s Guide, • Threads Primer: A Guide to Multithreaded Programming, Bil Lewis, Daniel J.Berg, Prentice Hall, 1996. 2000 운영체제
Solaris 2 Threads 2000 운영체제
Solaris Process (PCB) 2000 운영체제
Java Threads ~ • Thread 지원 방법 • Kernel(OS) 지원 • Library 지원 thread • Win32 library multithreading APIs: Windows 시스템 • pthread: POSIX 호환 시스템 • Language 지원: Java 뿐 • main(): a single thread • 다른 thread들 생성, 관리하는 명령 지원 • Thread 생성 • Thread class로부터 새 class 유도하고 run() 재정의:그림 5.7 참조 • start()가 (1) 메모리 할당하고새 thread 초기화, (2) run() 실행 • 절대로 직접 run()호출하지 말고 start()를 호출할 것! (초기화 때문) • Runnable interface를 구현하는 class를 정의하고 새 Thread 객체 생성 (그림 5.8 참조) • 주로 class가 이미 유도된 경우 이용 (예) public class ThreadedApplet extends Applet implements Runnable { … } • Java는 multiple inheritance 불가 2000 운영체제
Thread class 확장으로 thread 생성 class Worker1 extends Thread { public void run() { System.out.println(“I am a Worker Thread”); } } public class First { public static void main(String args[]) { Worker runner = new Worker1(); runner.start(); System.out.println(“I am the main thread”); } } 2000 운영체제
Runnable interface를 구현하여 thread 생성 public interface Runnable { public abstract void run(); } class Worker2 implements Runnable { public void run() { System.out.println(“I am a Worker Thread”); } } public class Second { public static void main(String args[]) { Runnable runner = new Worker2(); Thread thrd = new Thread(runner); thrd.start(); System.out.println(“I am the main thread”); } } 2000 운영체제
Java Threads ~ • Thread 관리 • Java의 thread 관리 APIs • suspend() • sleep() • resume() • stop() • multithreading 예: applet • 일반적으로 graphics, animation, audio 등 처리 • 처음 applet 실행될 때 start(), display 않는 동안 stop() • 그림 5.9 ClockApplet 참조 • Thread 상태 • New: new 문으로 thread 객체 생성 • Runnable: start() 호출로 메모리 할당하고 run() 호출한 상태 • Blocked: I/O, sleep(), suspend()로 block된상태 • Dead: stop() 호출된 상태 2000 운영체제
날짜와 시간 출력하는 ClockApplet import java.applet.* ; import java.awt.* ; public void ClockApplet extends Applet implements Runnable { public void run() { while(true) { try { thread.sleep(1000); } catch(InterruptedException e) { } repaint(); } } public void start() { if(clockThread == null) { clockThread = new Thread(this); clockThread.start() ; } else clockThread.resume(); } public void stop() { if(clockThread ! = null) clockThread.suspend() ; } public void destroy() { if(clockThread != null) { clockThread.stop() ; clokcThread = null ; } } public void paint(Graphics g) { g.drawString(new java.util.Date().toString(), 10, 30) ; } private Thread clockThread ; } 2000 운영체제
Java Threads • Thread와 JVM • JVM의 system-level threads • garbage-collector thread • timer events handling thread: sleep() • graphics control thread: 버튼 입력, 스크린 갱신 • JVM과 호스트 OS • Java threads = user threads • JVM이 Java threads 관리 • Windows NT: one-to-one model • Solaris 2.1~2.5: many-to-one model • Solaris 2.6~: many-to-many model • Multithreaded 해법 예제: Mailbox를 이용하는 생산자-소비자 문제 • 그림 5.11 The class server 참조 • 그림 5.12 Producer thread 참조 • 그림 5.13 Consumer thread 참조 2000 운영체제
Java Thread States 2000 운영체제
Producer Consumer Problem public class Server { public Server() { MessageQueue mailBox = new MessageQueue(); Producer producerThread = new Producer(mailBox); Consumer consumerThread = new Consumer(mailBox); producerThread.start(); consumerThread.start(); } public static void main(String args[]) { Server server = new Server(); } public static final int NAP_TIME= 5; } 2000 운영체제
Producer Thread class Producer extends Thread { public Producer(MessageQueue m) { mbox = m; } public void run() { Date message ; while (true) { int sleeptime = (int) (Server.NAP_TIME * Math.random()); System.out.println(“Producer sleeping for “ +sleeptime+ “seconds”); try { Thread.sleep(sleeptime*1000); } catch(InterruptedException e) { } //Produce an item and enter //it into the buffer message = new Date(); System.out.println(“Producer produced “ + message); mbox.send(message); } } private MessageQueue mbox; } 2000 운영체제
Consumer Thread class Consumer extends Thread { public Consumer(MessageQueue m) { mbox = m; } public void run() { Date message ; while (true) { int sleeptime = (int) (Server.NAP_TIME * Math.random()); System.out.println(“Consumer sleeping for “ +sleeptime+ “seconds”); try { Thread.sleep(sleeptime*1000); } catch(InterruptedException e) { } //consume an item for the buffer message = (Date)mbox.receive() ; if(message != null) System.out.println(“Consumer consumed “ +message); } } private MessageQueue mbox; } 2000 운영체제