5 장스레드 (Threads) 프로세스 = 자원 + PC 스레드 : 새 PC (a thread of control) 로같은 address space 를실행하는 fork 와유사 스레드 (Threads) 개요 ~ 경량프로세스 (LWP; lightweight process) = 스레드» CPU 를이용하는기본단위» thread ID, PC, 레지스터세트, 스택영역을가짐» 스레드들은서로같은프로세스의 code section, data section, OS resourcesopen 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 변경등 ) 5.1
Single and Multithreaded Processes 5.2
Single and Multithreaded Processes 5.3
스레드 (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) 5.4
스레드 (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) 5.5
사용자스레드와커널스레드 (User and kernel Threads) 사용자스레드 (User Threads)» user level 의 thread library 로구현 : 라이브러리가 thread 생성, 스케줄링, 관리담당» 불공평한스케줄링 (unfair scheduling)» 스위칭이빠름 (switching is fast)» single thread 인 kernel 에서사용자수준스레드가 blocking system call 을수행할경우 system call 완료까지다른모든스레드들은대기해야함» Three primary thread libraries: POSIX Pthreads: POSIX (Portable Operating System Interface) standard (IEEE 1003.1c) APIs (Solaris, Linux, Mac OS X) Java Threads Win32 Threads 커널스레드 (Kernel Threads)» 커널이 thread 생성, 스케줄링, 관리담당» 공평한스케줄링 (fair scheduling)» 스위칭시간이김 (switching is time consuming) : interrupt 처리때문» blocking system call 수행시커널이다른 thread 실행시킬수있음» Examples Windows XP/2000 Solaris Linux Tru64 UNIX Mac OS X 혼합접근 (hybrid approach) : Solaris 2 5.6
사용자스레드와커널스레드 (User and kernel Threads) kernel 자체 (system call 수행방법 )» single tasking : 초기 Unix kernel : 공유자료접근동기화불필요» multi tasking 동기적인시스템» Mach kernel : 스레드들은동기적임 (threads are synchronous), 다른스레드가제어를넘겨준다음에만수행가능 ( 공유데이타변경중에는제어를넘겨주지않음 ) 비동기적인시스템 : 잠금기법 (locking mechanism) 필요 5.7
다중스레드모델 (Multithreading Models) Many-to-One Model : 초기 Solaris Green threads, GNU Portable Threads» 다수의 user-level thread 가하나의 kernel thread 로매핑» 한 thread 가 blocking system call 하면전체프로세스 block One-to-One Model : Solaris 9 과이후버전, Linux, OS/2, Windows 95, 98, NT, 2000, XP» 각 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 9 prior, Windows NT/2000 ThreadFiber package» 다수의 user-level thread 들이더적거나같은수의 kernel threads 들로매핑 (multiplexed)» 동시성이덜좋음 (less concurrency): 커널은한순간에하나의 kernel thread 만스케줄» 특별한경우 : two-level model: 하나의 user-level thread 가하나의 kernel thread 로연결되는경우도지원 : Solaris 8 과이전버전, IRIX, Digital Unix, HP Tru64 UNIX 5.8
Many-to-One Model 5.9
One-to-one Model 5.10
Many-to-Many Model 5.11
Two-level Model 5.12
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) 이빠르다 문맥교환없고 CPU switching( 스레드문맥교환 ) 있음 종류» 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 이비교적빠르다. 5.13
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» Solaris 에서 ps elc 해보면 LWP 정보알수있음» ( 예 ) 동시에 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 없는데대기스레드있으면새 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. 5.14
Solaris 2 Threads 5.15
Solaris Process (PCB) 5.16
Threads 지원방법 Kernel(OS) 지원» Solaris Threads fork1(): fork() 와달리호출한스레드와연관된자료구조만복제 fork() + exec(): exec() 로주소공간제거 fork() + POSIX threads library (-lpthread)» Linux Threads Linux refers to them as tasks rather than threads Thread creation is done through clone() system call clone() allows a child task to share the address space of the parent task (process) Library 지원» POSIX Phread: /usr/include/pthread.h» Solaris Thread: /usr/include/thread.h» Windows XP Thread: Win32 library multithreading APIs Implements the one-to-one mapping Each thread contains» A thread id» Register set» Separate user and kernel stacks» Private data storage area The register set, stacks, and private storage area are known as the context of the threads The primary data structures of a thread include:» ETHREAD (executive thread block)» KTHREAD (kernel thread block)» TEB (thread environment block) Language 지원 : Java Thread 뿐» main(): a single thread» 다른 thread 들생성, 관리하는명령지원 5.17
Java Threads Java threads are managed by the JVM Java threads may be created by:» Extending Thread class» Implementing the Runnable interface Java Thread 생성 1 Thread class 로부터새 class 유도하고 run() 재정의 : 그림 5.7 참조 start() 가 (1) 메모리할당하고새 thread 초기화, (2) run() 실행 절대로직접 run() 호출하지말고 start() 를호출할것! ( 초기화때문 ) 2 Runnable interface 를구현하는 class 를정의하고새 Thread 객체생성 ( 그림 5.8 참조 ) 주로 class 가이미유도된경우이용 ( 예 ) public class ThreadedApplet extends Applet implements Runnable Java 는 multiple inheritance 불가 5.18
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 ); 5.19
Runnable interface 를구현하여 thread 생성 public interface Runnable public abstract void run(); /* Runnableinterface 코딩않음 */ 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 ); 5.20
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() 호출된상태 5.21
날짜와시간출력하는 ClockApplet import java.applet.* ; import java.awt.* ; public class 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() ; clockthread = null ; public void paint(graphics g) g.drawstring(new java.util.date().tostring(), 10, 30) ; private Thread clockthread ; 5.22
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 참조 5.23
Java Thread States 5.24
Producer-Consumer Problem public class Factory public Factory() // first create the message buffer Channel mailbox = new MessageQueue(); // now create the producer and consumer threads Thread producerthread = new Thread(new Producer(mailBox)); Thread consumerthread = new Thread(new Consumer(mailBox)); producerthread.start(); consumerthread.start(); public static void main(string args[]) Factory server = new Factory(); 5.25
Producer Thread class Producer implements Runnable private Channel mbox; public Producer(Channel mbox) this.mbox = mbox; public void run() Date message; while (true) SleepUtilities.nap(); message = new Date(); System.out.println("Producer produced " + message); // produce an item & enter it into the buffer mbox.send(message); 5.26
Consumer Thread class Consumer implements Runnable private Channel mbox; public Consumer(Channel mbox) this.mbox = mbox; public void run() Date message; while (true) SleepUtilities.nap(); // consume an item from the buffer System.out.println("Consumer wants to consume."); message = (Date)mbox.receive(); if (message!= null) System.out.println("Consumer consumed " + message); 5.27
MessageQueue: Mailbox 를이용하는생산자 - 소비자문제 Import java.util.*; public class MessageQueue public MessageQueue() queue = new Vector(); // This implements a nonblocking send public void send(object item) queue.addelement(item); // This implements a nonblocking receive public Object receive() Object item; if (queue.size() == 0) return null; else item = queue.firstelement(); queue.removeelementat(0); return item; private Vector queue; 5.28
5 장실습 ~mysung/thread/pthread.c 프로그램과 ~mysung/thread/thread.c 프로그램을코딩하여실행해보세요.» /usr/include/pthread.h 와 /usr/include/thread.h 참조» POSIX http://www.unix.org/version3/sample/functions/abort.html Windows XP thread (Win32 thread) Summation 프로그램을코딩하여실행해보세요. Win32 Summation 프로그램을아래버전으로각각만들어숙제디렉토리에제출하세요.» pthread 버전» thread 버전 5.29
Pthreads int sum; /* this data is shared by the thread(s) */ void *runner(void *param); /* the thread */ main(int argc, char *argv[]) pthread_t tid; /* the thread identifier */ pthread_attr_t attr; /* set of attributes for the thread */ /* get the default attributes */ pthread_attr_init(&attr); /* create the thread */ pthread_create(&tid,&attr,runner,argv[1]); /* now wait for the thread to exit */ pthread_join(tid,null); printf("sum = %d\n",sum); void *runner(void *param) int upper = atoi(param); int i; sum = 0; if (upper > 0) for (i = 1; i <= upper; i++) sum += i; pthread_exit(0); 5.30
Extending the Thread Class class Worker1 extends Thread public void run() System.out.println("I Am a Worker Thread"); public class First public static void main(string args[]) Worker1 runner = new Worker1(); runner.start(); System.out.println("I Am The Main Thread"); 5.31
The Runnable Interface public interface Runnable public abstract void run(); 5.32
Implementing the Runnable Interface 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"); 5.33
Joining Threads class JoinableWorker implements Runnable public void run() System.out.println("Worker working"); public class JoinExample public static void main(string[] args) Thread task = new Thread(new JoinableWorker()); task.start(); try task.join(); catch (InterruptedException ie) System.out.println("Worker done"); 5.34
Thread Cancellation Thread thrd = new Thread (new InterruptibleThread()); Thrd.start();... // now interrupt it Thrd.interrupt(); 5.35
Thread Cancellation public class InterruptibleThread implements Runnable public void run() while (true) /** * do some work for awhile */ if (Thread.currentThread().isInterrupted()) System.out.println("I'm interrupted!"); break; // clean up and terminate 5.36
Thread Specific Data class Service private static ThreadLocal errorcode = new ThreadLocal(); public static void transaction() try /** * some operation where an error may occur */ catch (Exception e) errorcode.set(e); /** * get the error code for this transaction */ public static Object geterrorcode() return errorcode.get(); 5.37
Thread Specific Data class Worker implements Runnable private static Service provider; public void run() provider.transaction(); System.out.println(provider.getErrorCode()); 5.38