*동기화
또는 통신이 필요하다.*상호작용
이 필요하다.*동기화 : 협력하는 프로세스 간에 실행 순서가 필요하다. ex)입금이 끝나야 출금이 수행되어야 한다.
*상호작용 : 제한된 자원을 공유하기 위함이며, 상호작용하는 프로세스는 순서에 맞게 실행되도록 동기화가 되어야 한다.
상호 배타적인 사용(Mutual exclusion)을 보장
해야 한다.동기화(Synchronization)문제
를 해결해야 한다. -> 프로세스 간에 순서를 정해서 한 프로세스만 처리한다.일관성
)Deadlock 문제
를 해결할 수 있어야 한다.임계구역에 있다
고 한다.*상호 배제
를 보장받아야 한다.*상호배제(Mutual Exclusion) : 하나의 프로세스만 공유 자원에 대해 배타적으로 접근하고 나머지 프로세스들은 공유 데이터의 접근할 필요가 있더라도 기다려야 한다.
수행중인 프로세스에서 save가 되기 전에 다른 프로세스가 수행되면 옳은 답이 나오지 않는다.
program mutex1;
var processnumber;
p0(){ //프로세스 p0의 임계구역 procedure
while(true){
while(processnumber != 0) //p1의 진입여부 확인
;
critical_section
processnumber = 1; //p1에게 임계구역 진입순서 양보
}
}
p1(){ //프로세스 p1의 임계구역 procedure
while(true){
while(processnumber != 1) //p0의 진입여부 확인
;
critical_section
processnumber = 1; //p0에게 임계구역 진입순서 양보
}
}
//main
processnumber = 1; //공유변수를 p1 진입 순서로 초기화
parbegin
p0(); //p0과 p1의 동시 수행 -> 어떤 것이 먼저 수행될지는 상황에 따라 변경
p1();
Parend
1단계 알고리즘은 상호배제를 만족시키지만 문제점이 있다.
program mutex2;
boolean p0_inside, p1_inside;
p0(){
while(true){
while(p1_inside == TRUE)
;
p0_inside = TRUE; //p0이 임계구역 진입시도
critical_section
p0_inside = FALSE; //p1에게 진입순서 양보
remainder section
}
}
p1(){
while(true){
while(p0_inside == TRUE)
;
p0_inside = TRUE; //p1이 임계구역 진입시도
critical_section
p0_inside = FALSE; //p0에게 진입순서 양보
remainder section
}
}
//main
p0_inside = false, p1_inside = false;
parbegin
p0();
p1();
Parend
2개의 프로세스가 병행하면서 한 줄씩 수행했을 때 문제점이 생긴다.
program mutex3;
boolean p0_inside, p1_inside;
p0(){
while(true){
p0_inside = TRUE;
while(p1_inside == TRUE)
;
critical_section
p0_inside = FALSE;
remainder section
}
}
p1(){
while(true){
p1_inside = TRUE;
while(p0_inside == TRUE)
;
critical_section
p1_inside = FALSE;
remainder section
}
}
//main
p0_inside = false, p1_inside = false;
parbegin
p0();
p1();
Parend
while문 수행 이전에 자신의 플래그(px_inside)를 true로 미리 변경한다.(상호배제는 보장) 하지만 교착상태가 발생(두 프로세스가 수행을 못하는 상태)할 위험이 있다.
program mutex3;
boolean p0_inside, p1_inside;
var processesnumber;
p0(){
while(true){
p0_inside = TRUE;
processesnumber = 1;
while(p1_inside == TRUE and processesnumber == 1)
;
//p0의 진입여부 확인
critical_section
p0_inside = FALSE;
remainder section
}
}
p1(){
while(true){
p1_inside = TRUE;
processesnumber = 0;
while(p0_inside == TRUE and processesnumber == 0)
;
//p1의 진입여부 확인
critical_section
p1_inside = FALSE;
remainder section
}
}
//main
p0_inside = false, p1_inside = false;
parbegin
p0();
p1();
Parend
3단계 상호 배제 알고리즘의 교착상태 발생 위험을 제거하고, 상호배제도 만족시킨다.
공유변수가 변경되는 동안 다른 프로세스가 공유변수에 접근하지 못하도록
혹은 인터럽트 발생을 허용하지 않도록 설정하면 된다.*TestAndSet(targer)
을 이용하여 임계구역 문제를 해결하고자 한다. (하드웨어 칩 이용)boolean TestAndSet(boolean & target){
boolean temp = target;
target = true;
return temp;
//target이 false인 경우, temp = false로 설정, false 반환
}
testandsetexample(){
boolean lock;
p0(){
while(true){
while(TestAndSet(lock))
;
critical section
lock = false;
remainder section
}
}
p1(){
while(true){
while(TestAndSet(lock))
;
critical section
lock = false;
remainder section
}
}
lock = false;
parbegin
p0();
p1();
parend
}
프로세스를 대기
시켜서 동작으로 임계구역에 진입하기 위한 연산(wait), S값을 감소
시킨다. (공유자원을 가져간다)대기 중인 프로세스를 깨우기
위해 신호를 보내는 동작으로 임계구역에서 나오기 위한 연산(signal), S값을 증가
시킨다. (공유자원을 반납한다)while(true){
P(S);
임계구역
while S <= 0 do no-operation; // S = 0 일 때 또 다른 프로세스가 공유자원을 요청하면 음수값을 방지
S = S - 1;
V(S);
잔류구역
S = S + 1;
}
semaphore mutex = 1;
-> 버퍼 접근에 대한 상호 배제를 위한 세마포어semaphore empty = n;
-> 버퍼에 비어 있는 항목의 개수를 위한 세마포어semaphore full = 0;
-> 버퍼에 채워져 있는 데이터의 개수를 위한 세마포어생산자
: 버퍼에 데이터를 넣기 위해 버퍼의 비어 있는 항목의 수(empty)를 1감소시킨다.소비자
: 버퍼에 채워진 데이터의 개수를 나타내는 full값을 1감소시킨다.semaphore wrt = 1;
-> 쓰기 프로세스 접근 시 배타적 사용을 위한 세마포어semaphore mutex = 1;
-> readcount 변수의 상호 배제를 위한 세마포어연산 : x.wait() or wait(x)
x.wait() or wait(x) 연산을 호출하는 프로세는 다른 프로세를 다음 연산이 호출될 때까지 중단시킨다. 세마포어의 P연산과 유사하고, x는 세마포어의 S와 유사하다.
연산 : x.signal() or signal(x)
x.signal() or signal(x)은 중단된 다른 프로세스를 재개시킨다. 세마포어의 V연산과 유사하다.
메시지 형식
송신측 및 수신측 식별자(identifier)길이, 형식(type), data로 구성된다.
메시지 발생 시 고려사항
naming 문제 : 메시지 교환에 관계되는 해당 프로세스들이 상대 프로세스를 설정하는 방법을 결정한다.
직접 네이밍과 간접 네이밍 방식의 두 가지 형태가 존재한다.
process A;
..
send(B, message); //A가 B에게 메시지를 보내겠다.
..
process B;
..
receive(A, message); //B가 A로부터 메시지를 받겠다.
..
process A;
..
send(mailbox1, message);
..
process B;
..
receive(mailbox1, message);
..
복사(Copying) 문제
버퍼링(Buffering) 문제
길이(Length) 문제
고정길이 메시지
: 구현이 용이하나, 버퍼의 크기에 비하여 메시지가 작을 경우 버퍼의 낭비를 초래하며, 반대로 메시지가 클 경우에는 메시지를 분할하여 전송해야 하는 문제점이 있다.가변길이 메시지
: 동적으로 버퍼를 생성하는 것으로 구현이 복잡하기는 하나 높은 적응력을 가진다.