각 코드의 문제점들은 임계구역 해결 조건을 다 충족하지 못하는데서 찾을 수 있다.
따라서 밑의 해결 조건을 우선 숙지한다.
임계구역 해결 조건
•
상호 배제
◦
임계구역 내에는 한 번에 하나의 프로세스만 있어야 한다.
•
한정 대기
◦
무한 대기이지 않아야 한다.
◦
특정 프로세스가 임계구역에 진입하지 못하면 안된다.
◦
교착상태 deadlock - 프로세스가 살아 있으나 작업이 진행되지 못하는 상태
•
진행의 융통성
◦
한 프로세스가 다른 프로세스의 진행을 방해하면 안된다.
◦
임계구역이 비어있으면 언제든 사용가능 해야 한다.
◦
딜레이??
4번. 다음 코드의 문제점을 설명하시오 - 상호 배제 문제
boolean lock = false; // 공유변수
// 프로세스 P1
while(lock==true);
lock=true;
[ 임계구역 ]
lock=false;
// 프로세스 P2
while(lock==true);
lock=true;
[ 임계구역 ]
lock=false;
Java
복사
•
while(lock==true); 에서 lock 이 false 인것을 확인하고 반복문을 빠져나오자마자 lock=true;을 실행하지 못한 채 타임아웃이 발생하면 상호배제 조건을 보장하지 못한다.
•
잠금이 풀릴 때 까지 반복문while(lock==true);을 실행하며 바쁜 대기를 한다.
++ 추가. 다음 코드의 문제점을 설명하시오. - 한정 대기 문제
// 공유변수
boolean lock1 = false;
boolean lock2 = false;
// 프로세스 P1
lock1 = true;
while(lock2==true);
[ 임계구역 ]
lock1 = false;
// 프로세스 P2
lock2 = true;
while(lock1==true);
[ 임계구역 ]
lock2 = false;
Java
복사
•
프로세스 시작하자마자 lock을 걸고 다른 프로세스가 잠금을 설정했는지 확인하는 것이 코드의 포인트
•
두 프로세스가 각 lock1 = true; 문을 실행하고 context switch가 발생한다면 P1이 while(lock2==true); 에서 무한루프를 돈다.
•
확장성 문제
◦
프로세스가 늘어나면 그 프로세스도 lock 상태를 확인하는 코드를 추가해야 해서 비효율적
5번. 다음 코드의 문제점을 설명하시오 - 진행의 융통성 문제
int lock = 1; // 공유변수
// 프로세스 P1
while(lock==2);
[ 임계구역 ]
lock=2;
// 프로세스 P2
while(lock==1);
[ 임계구역 ]
lock=1;
Java
복사
•
lock 값에 따라 어떤 프로세스가 임계구역을 사용하고 있는지 알 수 있음
•
잠금을 확인하는 문장이 하나라 상호배제와 한정 대기 보장
•
프로세스의 우선순위에 상관 없이 번갈아가며 진입한다. 한 프로세스가 두 번 연달아 임계구역에 진입하고 싶어도 못한다. - 경직된 동기화 lockstep synchronization
위 의 문제점들을 해결하기 위해 하드웨어적인 해결방법, 다양한 알고리즘을 만들어서 사용하고 있으며 모니터 방법을 통해 프로세스 간 통신을 하고 있다.
하드웨어적 방법
•
4번 문제의 코드에서 1,2줄 코드를 동시에 실행하게 한다.
•
편리하지만 바쁜대기를 통해 검사한다.
•
다른 알고리즘을 이와 같은 문제점을 해결한다.
6번. 파일을 이용하여 Test라는 문자를 주고받는 코드를 작성하시오.
부모 프로세스와 자식 프로세스가 파일을 이용하여 통신하는 코드이다.
우리가 주로 이해해야 하는 주요 개념은 file descriptor (fd) 가 상속되어 공유 된다는 것이다.
void main() {
int pid, fd;
char buf[5];
fd=open("test.txt", 0_RDWR); // test.txt 파일을 읽/쓰 권한으로 연다. O_RDONLY
// 🔴 fork() 이전에 파일을 open 함으로써 생성된 파일 기술자가 자식 프로세스에 상속된다.
pid=fork(); // pid : 프로세스 id , 부모pid는 0이다.
if(pid<0 || fd<0) {
exit(-1); // c프로그래밍에서 프로세스 강제종료문
}
// 자식
else if (pid==0) {
write(fd,"Test", 5);
close(fd);
exit(0); // c프로그래밍에서 프로세스 종료문
}
// 부모
else {
wait(0); // 부모가 먼저 실행되면 빈 내용을 읽게 되므로 자식 프로세스 기다림
lseek(fd, 0, SEEK_SET); // 파일 기술자가 맨 앞으로 옮겨진다.
read(fd, buf, 5);
printf("%s", buf);
close(fd);
exit(0);
}
}
Java
복사
•
fd의 위치, lseek의 이해
0 | 1 | 2 | 3 | 4 |
T | e | s | t | \0 |
lseek
◦
fd를 임의로 움직이는 명령어
◦
결국 위치 정보(fd)를 공유 하기 때문에 필요한 명령어이다.
파일을 이용한 통신
•
open -> write/read -> close
•
open()의 역할
◦
해당 파일이 있는지, 권한이 있는지 확인
◦
정상이라면 fd 반환
▪
file descriptor , 파일 기술자
▪
파일 접근 권한(like 열쇠)
•
파일을 이용한 통신은 부모-자식 관계 프로세스 간 통신에 많이 사용된다.
•
운영체제가 프로세스 동기화를 제공하지 않는다
◦
부모 프로세스가 wait() 함수를 이용하여 자식 프로세스의 작업이 끝날 때까지 기다렸다가 작업을 시작한다.