프로세스 동기화(Process Synchronization)

Slides:



Advertisements
Similar presentations
A 장형태.  병행프로세스 개요  상호배제 (Mutual Exclusion)  상호배제 ( 세마포어 )  모니터 (monitor)  프로세스간 2 가지 통신방법.
Advertisements

5 장 조건과 반복 ②. Contents Counting and Looping [while 문 사용 ] Powers of 2 [while 문 사용 ] More Guessing [do 문 사용 ] Election Day [do 문 사용 ] Finding Maximum &
운영체제 Chapter 3 병형 프로세스 박요안.
운영체제 3주차 정리 박 남 규.
10. 예외 처리.
DB 프로그래밍 학기.
DB 프로그래밍 학기.
컴퓨터 응용 및 실습 Part1. OOP&Java Programming data type Review
제 4 장 프로세스 Section 1 프로세스의 개념 Section 2 프로세스 스케줄링
9장. C 언어의 핵심! 함수. 9장. C 언어의 핵심! 함수 9-1 함수의 정의와 선언 main 함수 다시 보기 : 함수의 기본 형태 { } 그림 9-1.
제 6장 프로세스 간 동기화 및 통신 6.1 개요 6.2 병행 처리의 문제점
명품 JAVA Programming 제 13 장 스레드와 멀티태스킹.
명품 JAVA Essential.
Chapter 13 – 병렬 프로그래밍과 병렬 처리
어서와 Java는 처음이지! 제16장 스레드.
Concurrency: Mutual Exclusion and Synchronization (상호배제와 동기화)
Concurrency: Mutual Exclusion and Synchronization (상호배제와 동기화)
2주 실습강의 Java의 기본문법(1) 인공지능연구실.
Chapter 02 자바 기본구조 자바 프로그래밍의 기초적인 문법을 소개
프로세스 관리.
[ 단원 08 ] 예외처리와 스레드.
Internet Computing KUT Youn-Hee Han
제 6 장 프로세스 동기화 (Process Synchronization)
JAVA 프로그래밍 6장 객체지향프로그래밍의 핵심.
4장 병행 프로세스 병행성의 원리를 이해한다 병행 프로세스 수행과 관련된 상호 배 제 해결방안을 알아본다
CPU wait signal mutex 큐 준비 큐 … wait(mutex) 임계구역 signal(mutex) …
Chapter 6. 프로세스 동기화(Process Synchronization)
명품 Java Programming.
제2부 프로세스 관리(Process Management)
최용술 장 Thread 최용술
명품 JAVA Essential.
10장 다중 스레드 10.1 스레드 개요 10.2 Thread 클래스 10.3 스레드 생성
2장 자바환경과 자바 프로그램 2.1 자바 개발 환경 2.2 자바 통합환경 2.3 자바 응용 프로그램과 애플릿 프로그램
07. 디바이스 드라이버의 초기화와 종료 김진홍
Chapter 05. 클래스 완성. chapter 05. 클래스 완성 01. 복사 생성자 복사 생성(Copy Construction) 생성될 때 자신과 같은 타입의 객체를 변수로 받아, 이 객체와 같은 값을 갖는 새로운 객체를 생성하는 것 명시적인 생성 과정뿐만.
DataScience Lab. 박사과정 김희찬 (월)
5장 스레드 (Threads) 스레드 (Threads) 개요 ~
병렬 처리/컴퓨터 기초.
DK-128 실습 EEPROM 제어 아이티즌 기술연구소
Synchronization.
03. 병행 프로세스 (Parallel Process)
제 4주 2014년 1학기 강원대학교 컴퓨터학부 담당교수: 정충교
Chapter 6. 프로세스 동기화(Process Synchronization)
CPU wait signal mutex 큐 준비 큐 … wait(mutex) 임계구역 signal(mutex) …
제6장 프로세스 동기화(Process Synchronization)
4 병행 프로세스와 상호배제.
운영체제 (Operating Systems) (Process Synchronization)
5장 조건과 반복 ②.
DataScience Lab. 박사과정 김희찬 (월)
03. 안드로이드를 위한 Java 문법 제목. 03. 안드로이드를 위한 Java 문법 제목.
Ch.1 Iterator Pattern <<interface>> Aggregate +iterator
Readers & Writers 운영체제 7조 배 영 빈( ) 서 준 교( )
제 6 장 프로세스 동기화 (Process Synchronization)
Chap10 다중 스레드 Section 1 : 스레드 개요 Section 2 : Thread 클래스와 스레드 생명주기
병행 프로세스 이나현.
3장 운영체제 2C 김주성.
제 2장 어휘구조와 자료형 토 큰 리 터 럴 주 석 자 료 형 배 열 형.
Chapter6 : JVM과 메모리 6.1 JVM의 구조와 메모리 모델 6.2 프로그램 실행과 메모리 6.3 객체생성과 메모리
자바 5.0 프로그래밍.
2. 상호배제와 동기화 01 program versionone; // 첫 번째 버전
CACM 구현 public class CACM { public CACM(File file)
Java 3장. 자바의 기본 구조 I : 변수, 자료형, 연산자 public class SumTest {
제8장 쓰레드 프로그래밍.
병행프로세스의개요 주세호.
병행 프로세스 병행처리는 프로세스들이 서로 관계없이 독립적으 로 수행 가능하고 다른 프로세스들과 협력을 필요로 하면서 기능 수행 3.1 개요 parbegin/parend 제어문 : 순차적인 수행으로부터 여러 개의 동시 수행으로 갈라짐을 지시하는 명령어와 여러 개의 동시.
System Security Operating System.
03. 병행 프로세스(Parallel Process)
Concurrency: Mutual Exclusion and Synchronization (상호배제와 동기화)
병행 프로세스(Parallel Process)
3장 – 병행 프로세스 A 김정문.
Presentation transcript:

프로세스 동기화(Process Synchronization) 프로세스 협조 file 공유 logical address space 공유(thread) -> data (inconsistency) 자료 불일치 발생 가능 -> 프로세스 협조와 동기화 필요 배경(Background) ~ 공유 메모리를 이용한 생산자-소비자 문제 해결법 : 동기화에 count 이용 생산자 public class BoundedBuffer { public void enter(Object item) { // producer calls this method } 소비자 public Object remove() { // consumer calls this method } // potential race condition on count private volatile int count; }; 2000 운영체제

enter() Method & remove() Method // producer calls this method public void enter(Object item) { while (count == BUFFER_SIZE) ; // do nothing // add an item to the buffer ++count; buffer[in] = item; in = (in + 1) % BUFFER_SIZE; } // consumer calls this method public Object remove() { Object item; while (count == 0) ; // do nothing // remove an item from the buffer --count; item = buffer[out]; out = (out + 1) % BUFFER_SIZE; return item; } 2000 운영체제

배경(Background) 경합 상태(race condition) : 두 개의 프로세스가 경쟁적으로 한 변수를 조작 (예) 공유 변수 count의 변경 명령이 동시에 수행될 경우 불일치 발생 생산자의 count = count + 1; register1 = count; register1 = register1 + 1; count = register1; 소비자의 counter = counter - 1; register2 = count; register2 = register2 -1; count = register2; 병행 실행(concurrent execution) T0: 생산자 register1 := count {register1 = 5} T1: 생산자 register1 : = register1 + 1 {register1 = 6} T2: 소비자 register2 := count {register2 = 5} T3: 소비자 register2 := register2 - 1 {register2 = 4} T4: 생산자 count := register1 {counter = 6} T5: 소비자 count := register2 {counter = 4} 한 process만 접근하게 해야 함 2000 운영체제

임계 구역(The Critical-Section Problem)문제 임계구역 프로세스가 공유자료를 변경하는 코드영역 상호 배타적(mutually exclusive)이어야 함 프로세스 구조 진입 구역(entry section) : 진입허가 요청(한 프로세스만 실행) 출구 구역(exit section) 잔류 구역(remainer section) 임계구역 해결을 위한 3 요구 조건(requirements) R1. 상호 배제(mutual exclusion): 한 프로세스만 임계 구역 진입 R2. 진행(progress): 자연스럽게 막힘이 없이 진행, 임계구역에 진입할 프로세스 선택이 영원히 지연되지 않음 R3. 한계 대기(bounded waiting): 한 프로세스가 임계구역 진입 요청 후 기다리는데 한계가 있음 (no starvation) 기본 기계 명령어들(load, store, test)들은 원자적으로 실행됨(executed atomically)을 가정 2000 운영체제

2개 프로세스를 위한 해결법(Two-Tasks Solutions) ~ Algorithm 1 : turn 이용 R1(상호 배제) 만족 R2(진행) 불만 turn = 0 이고 P1은 진입 준비상태이고 P0가 잔류영역에 -> 영원히 P1 진입 불가 R3(한계 대기) 불만 Algorithm 2 : 진입준비 flag 이용 (P0 sets flag[0] = ture, P1 sets flag[1] = ture) R2(진행) 불만: flag[0] = true set 직후 flag[1] = true -> looping forever (flag[0] = true set 후 timer interrupt 가능한 환경 또는 병행실행 환경에서) 그래서 순서 바꾸면 -> 상호 배제 불만, 둘 다 CS 진입 R3(한계 대기) 불만: looping forever이므로 Algorithm 3 : 진입준비 flag + turn (Algorithm 1 + Algorithm 2) R1(상호배제) 만족: Pi는 turn=i 이거나 turn=j이어도 flag[j] = false 일 때 진입(flag[0]=flag[1]=true이어도 turn은 0 또는 1) R2(진행) 만족: flag[j] = false 이면 Pi 진입 OK, flag[j] = true 일 때 turn = i 또는 j, 이 때 turn=i 이면 Pi 진행, turn=j 이면 Pj 진행 후 flag[j] = false -> Pi 진입, 즉시 flag[I]=true로 재설정 되더라도 turn=j되므로 Pi는 Pj 1회 실행 후 진입 가능 R3(한계대기) 만족: Pi는 Pj 많아야 한번 진입 후 진입 진행됨(R2에서 처럼) 2000 운영체제

Worker Thread public class Worker extends Thread { public Worker(String n, int i, MutualExclusion s) { name = n; id = i; shared = s; } public void run() { while (true) { shared.enteringCriticalSection(id); // in critical section code System.Out.println(“Worker “ + name + “ in critical section”); shared.leavingCriticalSection(id); // out of critical section code System.Out.println(“Worker “ + name + “ out of critical section”); private String name; private int id; private MutualExclusion shared; 2000 운영체제

MutualExclusion Abstract Class public abstract class MutualExclusion { public static void criticalSection() { // simulate the critical section } public static void nonCriticalSection() { // simulate the non-critical section public abstract void enteringCriticalSection(int t); public abstract void leavingCriticalSection(int t); public static final int TURN_0 = 0; public static final int TURN_1 = 1; 2000 운영체제

Testing Each Algorithm public class TestAlgorithm { public static void main(String args[]) { MutualExclusion alg = new Algorithm_1(); Worker first = new Worker("Runner 0", 0, alg); Worker second = new Worker("Runner 1", 1, alg); first.start(); second.start(); } 2000 운영체제

Algorithm 1 public class Algorithm_1 extends MutualExclusion { public Algorithm_1() { turn = TURN_0; } public void enteringCriticalSection(int t) { while (turn != t) Thread.yield(); public void leavingCriticalSection(int t) { turn = 1 - t; private volatile int turn; 2000 운영체제

Algorithm 2 public class Algorithm_2 extends MutualExclusion { public Algorithm_2() { flag[0] = false; flag[1] = false; } public void enteringCriticalSection(int t) { int other; other = 1 - t; flag[t] = true; while (flag[other] == true) Thread.yield(); public void leavingCriticalSection(int t) { flag[t] = false; private volatile boolean[] flag = new boolean[2]; 2000 운영체제

Algorithm 3 public class Algorithm_3 extends MutualExclusion { public Algorithm_3() { flag[0] = false; flag[1] = false; turn = TURN_0; } public void enteringCriticalSection(int t) { int other = 1 - t; flag[t] = true; turn = other; while (flag[other] == true) && (turn == other)) Thread.yield(); public void leavingCriticalSection(int t) { flag[t] = false; private volatile int turn; private volatile boolean[] flag = new boolean[2]; 2000 운영체제

동기화 하드웨어(Synchronization Hardware) ~ CS 문제 -> CS동안 interrupt금지(no preemption) uniprocessor : interrupt disable로 해결 multiprocessor : interrupt로는 불가능 : message passing overhead hardware 명령(원자적으로 실행됨)으로 해결 Test-and-Set : 0->1, 1->1 Swap AT&T3B20 Read-and-Clean : 0->0, 1->0 한 처리기만 원래 값 읽고 나머지는 O을 읽음 원자적으로 실행(executed atomically) 중간에 인터럽트가 되지 않는 하나의 단위로 수행됨 하나의 기억장치 사이클 내에서 수행됨 Data structure for hardware solutions public { public HardwareData(boolean v) { data = v; } public boolean get() { return data; public void set(boolean v) { private boolean data; 2000 운영체제

동기화 하드웨어(Synchronization Hardware) ~ Test-and-Set instruction in Java Public class HardwareSolution { public static boolean testAndSet(HardwareData target) { // 원자적 수행 HardwareData temp = new HardwareData(target.get()); target.set(true); return temp.get(); } Thread using Test-and-Set lock HardwareData lock = new HardwareData(false); // lock 공유 while (true) { while (HardwareSolution.testAndSet(lock)) // 원자적 실행 Thread.yield(); criticalSection(); lock.set(false); nonCriticalSection(); 2000 운영체제

동기화 하드웨어(Synchronization Hardware) ~ Swap instruction public static void swap(HardwareData a, HardwareData b) { // 원자적 수행 HardwareData temp = new HardwareData(a.get()); a.set(b.get()); b.set(temp.get()); } Thread using swap HardwareData lock = new HardwareData(false); HardwareData key = new HardwareData(true); while (true) { key.set(true); do { HardwareSolution.swap(lock, key); // 원자적 실행 } while (key.get() == true); // now in critical section code lock.set(false); // out of critical section 2000 운영체제

세마포어(Semaphores) ~ Dijkstra 1965 세마포어 S 원자적 연산 wait(P:proberen, wait)와 signal(V:verhogen, increment)로 접근되는 정수 변수 P(S) { while S≤0 ; //no-op S--; } V(S) { S++; 이용(Usage) counting semaphore의 값은 무제한(unrestricted domain) binary semaphore의 값은 0 또는 1 counting semaphore S는 binary semaphore로 구현 가능 (초기값은 1, S가 0이 되면 모든 자원 이용 중이므로 S가 0이상이 될 때까지 대기) Semaphore S; P(S); criticalSection(); V(S); 2000 운영체제

세마포어(Semaphores) ~ public class Worker extends Thread { public Worker(Semaphore s, String n) { name = n; sem = s; } public void run() { while (true) { sem.P(); System.out.println(name + “ is in critical section.”); Runner.criticalSection(); sem.V(); System.out.println(name + “ is out of critical section.”); Runner.nonCriticalSection(); private Semaphore sem; private String name; 2000 운영체제

세마포어(Semaphores) ~ public final class Semaphore { public Semaphore() { value = 0; } public Semaphore(int v) { value = v; public synchronized void P() { // 원자적 실행 while (value <= 0) { try { wait(); catch (InterruptedException e) { } value --; public synchronized void V() { // 원자적 실행 ++value; notify(); private int value; 2000 운영체제

세마포어(Semaphores) ~ public class Runner { public static void criticalSection() { try { Thread.sleep( (int) (Math.random() * 3000) ); } catch (InterruptedException e) { } public static void nonCriticalSection() { public class FirstSemaphore public static void main(String args[]) { Semaphore sem = new Semaphore(1); Worker[] bees = new Worker[5]; for (int i = 0; i < 5; i++) bees[i] = new Worker(sem, “Worker ” + (new Integer(i)).toString()); for(int i = 0; i < 5; i++) bees[i].start(); 2000 운영체제

세마포어(Semaphores) ~ 효율적 구현(Implementation) 지금까지의 상호배제 해법들 : busy waiting(do no-op;)해야 함(단일 프로세서로 다중 프로그래밍할 때 문제 일으킴) 다른 말로 -> spinlock : 문맥 교환 없이 Lock상태에서 기다림 busy waiting 없는 세마포어 Wait으로 busy waiting하는 대신 자신을 중지 시키고(block itself) CPU는 다른 일을 하게 함 Wakeup으로 재시작 시킴 세마포어 S integer : 절대값은 세마포어 S에서 대기하고 있는 프로세스 개수 list : PCB들의 FIFO 큐 등 스케줄링 알고리즘에 따른 대기 큐 원자적 실행(executed atomically) 1. uniprocessor : 실행 수준 높여 interrupt방지 2. mutiprocessor : 임계영역 문제 해결 방법들(Ex) turn+flag algo, bakery algo) busy waiting 없는 세마포어: Critical Section이긴 응용에서 busy waiting해결하는 방법임 Linux의 세마포어 원자적 연산 구현: P(S)에서 process status를 TASK_UNINTERRUPTIBLE로 uninterruptible하게 만들고 CPU 스케줄링 호출하여 실행, V(S)에서 TASK_RUNNING으로 interruptible하게 복귀(Linux Kernel Internals, 2nd Ed., p34~36 참조) 2000 운영체제

세마포어(Semaphores) ~ P(S) { value--; if(value<0) { add this process to list block; } V(S) { value++; if(value≤0) { remove a process P from list wakeup(P); } 2000 운영체제

세마포어(Semaphores) 교착상태(Deadlock)와 기아상태(Starvation) deadlock(두개 이상의 프로세스가 현재 대기중인 프로세스에 의해서만 일어날 수 있는 event를 무한히 기다림) (예) P0 ← deadlocked P(S); P(Q); .... V(S); V(Q); 기아상태(starvation) 또는 무한 정지(indefinite blocking) 세마포어 안에서 무한히 기다림 (예) 세마포어의 대기 리스트를 LIFO 순으로 처리하면 -> Starvation → P1 (초기값 S=1, Q=1) P(Q); P(S); …. V(Q); V(S); 2000 운영체제

동기화의 고전적인 문제들(Classical Problems of Synchronization) semaphore를 이용한 동시성 제어(concurrency-control) 문제 유한 버퍼 생산자-소비자 문제(Bounded-Buffer Problem) 판독자와 기록자 문제(Readers and Writers Problem) 식사하는 철학자 문제(Dining-Philosophers Problem) 2000 운영체제

유한버퍼 생산자-소비자 문제(The Bounded-Buffer Problem) BoundedBuffer class public class BoundedBuffer { public BoundedBuffer() { // buffer is initially empty count = 0; in = 0; out = 0; buffer = new Object[BUFFER_SIZE]; mutex = new Semaphore(1); empty = new Semaphore(BUFFER_SIZE); full = new Semaphore(0); } public void enter() { /* see next slides */ } public Object remove() { /* see next slides */ } private static final int BUFFER_SIZE = 2; private Semaphore mutex; private Semaphore empty; private Semaphore full; private int in, out; private Object[] buffer; 2000 운영체제

유한버퍼 생산자-소비자 문제(The Bounded-Buffer Problem) The enter() method public void enter(Object item) { empty.P(); mutex.P(); // add an item to the buffer ++count; buffer[in] = item; in = (in + 1) % BUFFER_SIZE; if (count == BUFFER_SIZE) System.out.println(“Producer Entered “ + item + “Buffer FULL”); else System.out.println(“Producer Entered “ + item + “Buffer Size =“ + count); mutex.V(); full.V(); } 2000 운영체제

유한버퍼 생산자-소비자 문제(The Bounded-Buffer Problem) The remove() method public Object remove() { full.P(); mutex.P(); // remove an item from the buffer Object item = buffer[out]; out = (out + 1) % BUFFER_SIZE; mutex.V(); empty.V(); return item; } 2000 운영체제

유한버퍼 생산자-소비자 문제(The Bounded-Buffer Problem) 생산자 Thread import java.util.*; public class Producer extends Thread { public Producer(boundedBuffer b) { buffer = b; } public void run() { Date message; while(true) { BoundedBuffer.napping(); // produce an item & enter it into the buffer message = new Date(); System.out.println(“Producer produced “ + message); private BoundedBuffer buffer; 2000 운영체제

유한버퍼 생산자-소비자 문제(The Bounded-Buffer Problem) 소비자 Thread import java.util.*; public class Consumer extends Thread { public Consumer(boundedBuffer b) { buffer = b; } public void run() { Date message; while (true) { BoundedBuffer.napping(); // consume an item from the buffer System.out.println(“Consumer wants to consume”); message = (Date)buffer.remove(); private BoundedBuffer buffer; 2000 운영체제

유한버퍼 생산자-소비자 문제(The Bounded-Buffer Problem) BoundedBufferServer public class BoundedBufferServer { public static void main(String args[]) { BoundedBuffer server = new BoundedBuffer(); // now create the producer and consumer threads Producer producerThread = new Producer(server); Consumer consumerThread = new Consumer(server); producerThread.start(); consumerThread.start(); } 2000 운영체제

판독자와 기록자 문제(The Readers and Writers Problem) writer : 읽고 쓰기(update) -> 공유 데이터에 단독 접근해야 (exclusive access) 유형 1 : writer가 대기 중이더라도 writer가 실제로 공유자료를 접근하지 않는 한 reader는 기다리지 않음 -> Writers may starve. Reading중이면 다른 reader도 수행가능 Writer는 reader가 없을 때 공유자료 접근 유형 2 : writer가 대기중이면 reader는 기다림 -> Readers may starve. -> 다른 기아상태 없는 해법들 있음 2000 운영체제

동기화의 고전적인 문제들(Classical Problems of Synchronization) ~ Reader public class Reader extends Thread { public Reader(Database db) { server = db; } public void run() { int c; while (true) { c = server.startRead(); // now reading the database c = server.endRead(); private Database server; 2000 운영체제

동기화의 고전적인 문제들(Classical Problems of Synchronization) ~ Writer public class Writer extends Thread { public Writer(Database db) { server = db; } public void run() { while (true) { server.startWrite(); // now writing the database server.endWrite(); private Database server; 2000 운영체제

동기화의 고전적인 문제들(Classical Problems of Synchronization) ~ The database for the readers-writers problems public class Database { public Database() { readerCount = 0; mutex = new Semaphore(1); db = new Semaphore(1); } public int startRead() { /* see next slides */ } public int endRead() { /* see next slides */ } public void startWrite() { /* see next slides */ } public void endWrite() { /* see next slides */ } private int readerCount; // number of active readers Semaphore mutex; // controls access to readerCount Semaphore db; // controls access to the database 2000 운영체제

동기화의 고전적인 문제들(Classical Problems of Synchronization) ~ Methods called by readers public int startRead() { mutex.P(); ++readerCount; // if Iam the first reader tell all others // that the database is being read if (readerCount == 1) db.P(); mutex.V(); return readerCount; } public int endRead() { mutex.P(); --readerCount; // if I am the last reader tell all others // that the database is no longer being read if (readerCount == 0) db.V(); mutex.V(); return readerCount; } 2000 운영체제

동기화의 고전적인 문제들(Classical Problems of Synchronization) ~ Methods called by writers public void startWrite() { db.P(); } public void endWrite() { db.V(); 2000 운영체제

동기화의 고전적인 문제들(Classical Problems of Synchronization) ~ 식사하는 철학자 문제(The Dining Philosophers Problem) Shared data Semaphore chopStick[] = new Semaphore[5]; 2000 운영체제

식사하는 철학자 문제(The Dining Philosophers Problem) ~ Philosopher i: while (true) { // get left chopstick chopStick[i].P(); // get right chopstick chopStick[(i + 1) % 5].P(); // eat for awhile //return left chopstick chopStick[i].V(); // return right chopstick chopStick[(i + 1) % 5].V(); // think for awhile } 2000 운영체제

식사하는 철학자 문제(The Dining Philosophers Problem) 식사하는 철학자 문제(The Dining-Philosophers Problem) : Dijkstra 차원(chostick)을 프로세스(philosophers)들에게 deadlock이나 starvation 없이 할당하는 문제 문제점 1: 만일 이웃하는 철학자가 동시에 식사할 수 있게 하면 deadlock 가능 교착상태 없는 식사하는 철학자 문제 해법들 해법 ① : 4명 까지만 동시에 식탁에 앉게 함 해법 ② : 양쪽 chopstick이 사용가능 할 때만 chopstick 잡게 함 해법 ③ : Asymmetric solution : 홀수번째 철학자들은 왼쪽 chopstick 먼저 잡게 하고, 짝수번째 철학자들은 오른쪽 chopstick 먼저 잡게 함 문제점 2 : starvation : 어떤 경우라도 한 철학자가 굶는 일 없게 해야 함->각자 2000 운영체제

Monitors ~ Semaphore 이용에서의 timing errors (producer-consumers count 에서도) 실행 순서가 틀릴 경우 세마포어를 잘못 사용하는 경우 (1) signal(mutex); 임계구역 wait(mutex); 상호배제 위반(violates mutual execulusion) (2) wait(mutex); 교착상태(deadlock) (3) wait(mutex) 또는 signal(mutex)을 빼먹으면 상호배제 위반 또는 교착상태 고급 언어 동기화 구조체로 해결 모니터(monitor) 프로그래머가 동기화 프로그래밍 하다 실수하는 대신 컴파일러가 정확한 프로그램 지원 2000 운영체제

모니터(Monitors) ~ monitor monitor-name { // variable declarations public entry p1(…) { … } public entry p2(…) { 모니터 : 한 순간에 한 프로세스만이 모니터 안에서 활성화 되게 만들어진 고급언어 구조체 : p202 그림 7.26 모니터를 powerful 하게 보완 -> 모니터 + condition(프로그래머 재량) 한 procedure가 중간에 block되었다가 조건이 만족되면 다시 진행 P가 x.signal한 후의 처리(Q는 x.wait) 1. Signal-and-Wait: P는 Q가 모니터를 떠나기를 기다리거나 다른 조건을 기다림 2. Signal-and-Continue: Q는 P가 모니터를 떠나기를 기다리거나 다른 조건을 기다림 1+2 : Concurrent Pascal : P는 signal후 즉시 monitor를 떠나고 Q가 재시작 : 한 프로시주어 안에서 한 signal만 가능 2000 운영체제

Monitor with condition variables 2000 운영체제

모니터(Monitors) ~ 식사하는 철학자 Version 2 : 교착상태 없는 식사하는 철학자들의 문제 해법 ② 이웃하는 철학자는 동시에 식사할 수 없게 하는 방법(굶는 일은 있음 : 해결 연구!) 철학자 작업 : dp.pick up(i)...eat...dp.put down(i) -> chopstick분배 monitor diningPhilosophers { int[] state = new int[5]; static final int THINKING = 0; static final int HUNGRY = 1; static final int EATING = 2; condition[] self = new condition[5]; public diningPhilosophers { for (int i = 0; i < 5; i++) state[i] = THINKING; } public entry pickUp(int i) { /* see next slides */ } public entry putDown(int i) { /* see next slides */ } private test(int i) {/* see next slides */ } 2000 운영체제

모니터(Monitors) ~ public entry pickUp(int i) { private test(int i) { state[i] = HUNGRY; test(i); if (state[i] != EATING) self[i].wait; } private test(int i) { if ( (state[(i + 4) % 5] != EATING) && (state[i] == HUNGRY) && (state[(i + 1) % 5] != EATING) ) { state[i] = EATING; self[i].signal; } public entry putDown(int i) { state[i] = THINKING; // test left and right neighbors test((i + 4) % 5); test((i + 1) % 5); } 2000 운영체제