## 목차 ##
## 1. 프로세스 간 통신 ##
(1) 프로세스 간 통신의 개념
프로세스 간 통신(Inter Process Communication - IPC)
- 같은 컴퓨터에 있는 다른 프로세스와의 통신
- 네트워크로 연결된 다른 컴퓨터 프로세스와의 통신
프로세스 내부 통신
- 프로세스 내 스레드끼리의 통신
- 전역변수, 파일을 이용하여 데이터 교환
프로세스 간 데이터 통신
- 같은 컴퓨터의 프로세스 간 통신
- 공용파일, 운영체제가 제공하는 파이프를 통해 데이터 교환
네트워크 데이터 통신
- 원격 컴퓨터 프로세스 간 통신
- 소켓을 통해 데이터 교환
- ex) RPC(원격 프로시저 호출)
(2) 프로세스 간 통신의 분류
방향에 따른 분류
- 양방향 통신 : 동시에 양쪽 방향으로 전송 가능. 일반적인 통신 방법이다. ex) 소켓
- 반양방향 통신 : 양쪽 방향으로 전송할 수 있지만 동시 전송은 불가능. ex) 무전기
- 단방향 통신 : 한쪽 방향으로만 전송 가능. 프로세스간 통신에서 전역변수와 파이프가 여기에 해당한다.
- ex) 1개의 전역변수에 두 프로세스가 데이터를 동시에, 혹은 차례로 전송하면 하나는 지워지기때문에 이는 단방향 통신에 해당한다.
통신 구현에 따른 분류
- 동기화 통신
- 데이터가 도착했음을 알려주는 기능이 있는 통신
- ex) 파이프, 소켓
- 비동기 통신
- 반복루프 등을 통해 데이터가 도착했는지를 주기적으로 확인하는 바쁜 대기(busy wait) 방식을 사용하는 통신
- ex) 전역변수, 파일
- 동기화 통신
(3) 프로세스 간 통신의 종류
전역변수
- 데이터를 보내는 쪽에서 전역변수에 값을 write
- 데이터를 받는 쪽에서 전역변수의 값을 read
- 부모 프로세스가 전역변수 선언 후 자식 프로세스를 만들면 통신을 할 수 있다.
- 쓰기 프로세스가 데이터를 언제 쓸지 알 수 없어 반복루프를 통해 계속 확인해야 한다.(바쁜 대기)
파일
- open : 파일 기술자(file descriptor) 획득(파일 열기)
- read/write : 파일 기술자를 통해 파일 입출력
- close : 파일 기술자 반납(파일 닫기)
- 이 방식은 부모-자식 관계의 프로세스들 사이에 많이 사용된다.
- 부모 프로세스가 wait()함수를 사용하여 자식 프로세스를 기다려주는 자체 동기화 방식 사용
파이프
- 운영체제 동기화 지원
- 파일과 비슷하게 open() 함수로 기술자 획득
- close() 함수로 마무리
- 이름 없는 파이프
- 일반적인 파이프
- 부모-자식, 형제 프로세스와 같이 관련 있는 프로세스 간 통신에 사용
- 이름 있는 파이프
- FIFO라 불리는 특수 파일을 사용
- 관련 없는 프로세스 간 통신에 사용
소켓
- 주로 원격에 있는 프로세스와의 통신에 사용
- 자신의 소켓과 상대 프로세스의 소켓을 바인딩(binding)
- 프로세스가 자신의 소켓에 데이터를 쓰면 바인딩 된 프로세스가 소켓을 통해 읽을 수 있다.
- 운영체제 동기화 지원
## 2. 공유 자원과 임계구역 ##
(1) 공유 자원 접근
- 2개 이상의 프로세스가 공유 자원을 병행적으로 읽거나 쓰는 상황
- 경쟁 조건이라고 한다.
- 공유자원 접근 순서에 따라 실행 결과가 달라질 수 있다.
- 두 번째 프로세스가 실행한 결과를 첫 번째 프로세스가 다시 덮어쓴다.
(2) 임계구역
- 임계구역(critical section)
- 공유자원 접근 순서에 따라 실행 결과가 달라지는 프로그램의 영역
- 임계 구역에서는 프로세스들이 동시에 작업하면 안된다.
- 한 프로세스가 임계구역에서 작업 중일때는 다른 프로세스는 기다려야한다.
(3) 생산자-소비자 문제
- 생산자 프로세스, 소비자 프로세스는 독립적으로 작업
- 생산자 프로세스는 데이터를 버퍼에 쓰기
- 소비자 프로세스는 버퍼에서 데이터를 읽기
- 전역변수 sum은 버퍼에 있는 데이터의 갯수
현재 sum이 3인 상태에서 생산자가 1개를 추가, 소비자가 1개를 빼가려 하는 상황을 가정해보자.
- 현재 sum=3 → 생산자 sum=4 계산 → 소비자 sum=2 계산 → 소비자 sum=2 저장 → 생산자 sum=4 저장
- 위와 같은 순서로 일어나면 실제 데이터는 3개인데 sum이 4가 된다.
하드웨어 자원들은 임계 구역이다.
(4) 임계구역 해결 조건
상호 배제(mutual exclusion)
- 한 프로세스가 임계구역 내에 있을때 다른 프로세스는 임계구역에 들어갈 수 없다.
한정 대기(bounded waiting)
- 임계구역을 진입하려는 프로세스가 무한대기하지 않아야한다.
진행의 융통성(progress flexibility)
- 한 프로세스가 다른 프로세스의 진행을 방해하면 안된다.
- 임계구역이 비어있으면 프로세스는 항상 임계구역에 진입할 수 있다.
## 3. 임계구역 해결 방법 ##
임계구역 문제를 해결하는 단순한 방법은 잠금(lock)이다. 하나의 프로세스가 임계구역에 진입해있는 동안 빠져나오기 전까지 lock을 걸어 다른 프로세스의 진입을 막는 것이다.
(1) 기본 코드 소개
임계구역 코드 진입 전 lock인지 확인 후 lock이면 대기
임계구역에 진입할 대는 lock을 걸고 임계구역에서 빠져나올때는 lock을 해제한다.
...
while(lock == true); //lock이면 대기
lock = true; // 락
//임계구역
lock = false; // 락 해제
...
(2) 임계구역 해결 조건을 고려한 코드 설계
- 상호 배제 문제
while(lock == true);
//여기서 프로세스1 타임아웃 -> 프로세스2가 lock == false 확인 후 임계구역 진입 -> 프로세스 2 타임아웃 -> 프로세스 1 임계구역 진입
lock = true;
//임계구역
lock = false;
위 코드는 상호 배제를 충족하지 않는다. 두 프로세스가 동시에 임계구역에 진입할 가능성이 존재한다.
- 한정 대기 문제
프로세스1 코드
lock1 = true;
while(lock2 == true);
//임계구역
lock1 = false;
프로세스2 코드
lock2 = true;
while(lock1 == false);
//임계구역
lock2 = false;
위 코드는 잠금을 하고 다른 프로세스의 진입을 확인하므로 상호 배제가 보장된다.
만약 프로세스1이 lock1 = true;
를 실행하고 타임아웃 된 다음 문맥교환 후 프로세스2가 lock2 = true;
를 실행하고 타임아웃 된다면? 이후로는 두 프로세스 모두 while문을 벗어나지 못한다. 따라서 위 코드는 한정대기 문제를 충족하지 못한다. 이러한 상황을 교착상태(deadlock)라고 한다. 즉, 프로세스가 살아있으나 진행되지 못함을 의미한다.
- 진행의 융통성 문제
프로세스1 코드
while(lock == 2);
//임계구역
lock = 2;
프로세스2 코드
while(lock == 1);
//임계구역
lock = 1;
한 프로세스가 사용후에는 항상 lock을 다른 프로세스의 숫자로 바꾸어놓는다. 따라서 다른 하나의 프로세스가 임계구역 진입 후 lock 값을 바꾸기 전까지는 임계구역에 진입할 수 없다. 항상 번갈아가며 실행될 수밖에 없다. 이러면 임계구역이 사용중이지 않더라도 다른 프로세스가 사용할 때까지 기다려야한다. 따라서 진행의 융통성 문제를 보장하지 못한다.
- 검사와 지정
- 하드웨어적으로 여러 명령어가 동시에 실행되도록 하는 기법
- 명령어를 실행하는 도중에 타임아웃이 걸리지 않도록 하는 방식(원자성 - atomicity)
while(testandset(&lock)==true);
//lock==true이면 대기하다가 false이면 true로 바꾸고 반복문 탈출
(3) 피터슨 알고리즘
프로세스1
lock1 = true;
turn = 2;
while(lock2 == true && turn == 2);
//임계구역
lock1 = false;
프로세스2
lock2 = true;
turn = 1;
while(lock1 == true && turn == 1);
//임계구역
lock2 = false;
두 프로세스 모두 락을 걸었더라도 turn 변수로 다른 프로세스에 차례를 양보하게 된다. turn 변수는 1 혹은 2중 하나만 가질 수 있으므로 두 프로세스 중 1개는 항상 임계구역에 진입할 수 있어 한정 대기 문제를 해결한다.
- 피터슨 알고리즘은 임계구역 조건 3가지를 모두 충족한다.
- 프로세스가 추가되면 공유변수를 추가하고 코드를 변경해야한다.
- 구조가 복잡하여 현재 잘 사용하지 않는다.
- 반복루프로 바쁜대기를 사용하여 자원을 낭비한다.
(4) 데커 알고리즘
프로세스1
lock1 = true;
while(lock2 == true) {
if(turn == 2) {
lock1 = false;
while(turn == 2);
lock1 = true;
}
}
//임계구역
turn = 2;
lock1 = false;
프로세스2
lock2 = true;
while(lock1 == true) {
if(turn == 1) {
lock2 = false;
while(turn == 1);
lock2 = true;
}
}
//임계구역
turn = 1;
lock2 = false;
- 데커 알고리즘은 임계구역 조건 3가지를 모두 만족한다.
- 프로세스가 추가되면 공유변수를 추가하고 코드를 변경해야한다.
- 구조가 복잡하여 현재 잘 사용하지 않는다.
- 반복루프로 바쁜대기를 사용하여 자원을 낭비한다.
(5) 세마포어
피터슨, 데커 알고리즘의 바쁜대기(busy wait) 사용으로 인한 자원의 낭비를 해결
방법이 간단하고 사용이 쉽다.
semaphore(n) {
RS = n;
}
P() {
if(RS > 0)
RS--;
else
block();
}
/****
임계구역
*****/
V() {
RS++;
wake_up();
}
semaphore(n)
: RS를 n으로 초기화한다. n은 사용 가능한 자원의 수P 연산 : RS가 0보다 크면 1 감소시키고 임계구역 진입. 0 이하면 자원이 생길때까지 기다린다.
V 연산 : RS값 1 증가. 대기중인 프로세스에 wakeup 신호 전송
세마포어 큐
- 임계구역이 잠금일 때 진입을 대기하는 프로세스들이 저장되어있는 큐
- wake_up 신호를 받으면 큐의 첫 번째 프로세스가 임계구역 진입
세마포어의 유형
- count semaphore
- 사용 가능한 자원의 수 사용
- 위에서 봤던 코드가 여기에 해당
- binary semaphore
- 1개의 프로세스만 진입 가능
- 사용중이면 0, 사용가능이면 1
- count semaphore에서 n이 1인 경우에 해당
- count semaphore
## 4. 파일, 파이프, 소켓 프로그래밍 ##
(1) 순차 파일
아무리 큰 파일도 데이터는 개념적으로 한 줄이다.
- ex) Operating\nSystem\nStudy\0
- 이것을 순차 파일(sequential file)이라 한다.
파일을
open()
하면 파일 기술자(file descriptor)를 얻는다.- 모든 파일은
open()
,read()
,write()
,close()
구조다. - 파일 기술자는 파일 열기 방식(read-only, read-write 등), 파일 접근 권한, 커서 위치 등의 정보를 저장한다.
- 파일을
open()
후 프로세스를fork()
하면 파일 기술자는 자식 프로세스에 상속되고 이를 공유한다.
- 모든 파일은
(2) 파이프
운영체제 동기화를 지원하는 단방향 통신
- 보통 파이프라 하면 이름없는 파이프를 지칭
파이프는 부모-자식 프로세스 혹은 같은 부모를 가진 자식 프로세스 간 통신에 사용된다.
파일 기술자를 사용한다.
- 읽기/쓰기 기술자가 따로 존재한다.(fd[0], fd[1])
파이프는 대기가 있는 통신이다.
read(fd[0], buffer, byte)
를 실행하면 파이프로 메시지가 들엉로 때까지 대기한다.- 파일처럼 부모,자식 프로세스간의 순서를 위해
wait()
로 프로세스가 직접 동기화를 할 필요가 없다.
(3) 네트워킹
- 네트워크로 연결된 원격 컴퓨터의 프로세스간의 통신 방법
- 파일과 유사하게
open()
,read()
,write()
,close()
구조로 되어있다. - 양방향 동기화 통신
- 파일과 유사하게
클라이언트는 파일, 파이프에 비해 특별히 추가되는 절차가 없다.
서버는 소켓 생성 후
bind()
를 통해 포트에 소켓을 등록한다.- 포트(port)는 한 IP에서 특정 프로세스와의 통신을 위한 구분 번호이다.
- 하나의 포트에는 여러 소켓을 등록할 수 있다.
- 소켓 등록후에는
listen()
이 실행되어 클라이언트의connect()
요청을 기다린다. - 클라이언트
connect()
요청이 도착하고accept()
되면 소켓 기술자를 생성해 통신을 시작한다. close()
를 통해 소켓 기술자를 닫고listen()
으로 돌아간다.
'CS > 운영체제' 카테고리의 다른 글
(운영체제) 7 - 물리 메모리 관리 (0) | 2020.05.15 |
---|---|
(운영체제) 6 - 교착 상태(데드락) (0) | 2020.05.15 |
(운영체제) 4 - CPU 스케줄링 (0) | 2020.05.15 |
(운영체제) 3 - 프로세스와 스레드 (0) | 2020.05.15 |
(운영체제) 2 - 컴퓨터의 구조와 성능 향상 (0) | 2020.05.15 |