728x90
1. 프로세스 간 통신
1. 프로세스 간 통신의 개념
프로세스는 시스템 내에서 독립적으로 실행되기도 하고 데이터를 주고받으며 협업하기도 함
프로세스가 다른 프로세스와 데이터를 주고받는 프로세스 간 통신(IPC)에는 같은 컴퓨터 내에 있는 프로세스뿐만 아니라 네트워크로 연결된 다른 컴퓨터에 있는 프로세스와의 통신도 포함됨
프로세스 간 통신의 종류
- 프로세스 내부 데이터 통신 : 하나의 프로세스 내에 2개 이상의 스레드가 존재하는 경우의 통신이다. 프로세스 내부의 스레드는 전역 변수나 파일을 이용하여 데이터를 주고 받는다.
- 프로세스 간 데이터 통신 : 같은 컴퓨터에 있는 여러 프로세스끼리 통신하는 경우로, 공용 파일 또는 운영체제가 제공하는 파이프를 사용하여 통신한다.
- 네트워크를 이용한 데이터 통신 : 여러 컴퓨터가 네트워크로 연결되어 있을 때도 통신이 가능한데, 이 경우 프로세스는 소켓을 이용하여 테이터를 주고받는다. 이처럼 소켓을 이용하는 프로세스 간 통신을 네트워킹이라고 한다. 다른 컴퓨터에 있는 함수를 호출하여 통신하는 원격 프로시저 호출도 여기에 해당한다.
2. 프로세스 간 통신의 분류
2.1 통신 방향에 따른 분류
양방향 통신 | 데이터를 동시에 양쪽 방향으로 전송할 수 있는 구조로, 일반적인 통신은 모두 양방향 통신이다. 프로세스 간 통신에서는 소켓 통신이 양방향 통신에 해당한다. |
반양방향 통신 | 데이터를 양쪽 방향으로 전송할 수 있지만 동시 전송은 불가능하고 특정 시점에 한쪽 방향으로만 전송할 수 있는 구조이다. 반양방향 통신의 대표적인 예는 무전기이다. |
단방향 통신 | 모스 신호처럼 한쪽 방향으로만 데이터를 전송할 수 있는 구조이다. 프로세스 간 통신에서는 전역 변수와 파이프가 단방향 통신에 해당한다. |
2.2 통신 구현 방식에 따른 분류
대기가 있는 통신 | 동기화를 지원하는 통신 방식이다. 데이터를 받는 쪽은 데이터가 도착할 때까지 자동으로 대기 상태에 머물러 있는다. |
대기가 없는 통신 | 동기화를 지원하지 않는 통신 방식이다. 데이터를 받는 쪽은 바쁜 대기를 사용하여 데이터가 도착했는지 여부를 직접 확인한다. |
*동기화 : 데이터가 도착했음을 알려주는 것
프로세스 간 통신의 분류
분류 방식 | 종류 | 예 |
통신 방향에 따른 분류 | 양방향 통신 | 일반적 통신, 소켓 |
반양방향 통신 | 무전기 | |
단방향 통신 | 전역 변수, 파일, 파이프 | |
통신 구현 방식에 따른 분류 | 대기가 있는 통신(동기화 통신) | 파이프, 소켓 |
대기가 없는 통신(비동기화 통신) | 전역 변수, 파일 |
3. 프로세스 간 통신의 종류
3.1 전역 변수를 이용한 통신
- 공동으로 관리하는 메모리를 사용하여 데이터를 주고 받는 것
- 주로 직접적으로 관련이 있는 프로셋 간에 사용
- 서로 연관이 없는 프로세스 간 통신에도 exterm 변수와 같은 전역 변수 사용 가능
3.2 파일을 이용한 통신
- 파일 열기
- open("파일.txt", O_RDWR) : fd(파일 기술자) 반환
- fd : 해당 파일에 접근할 수 있는 일종의 열쇠
- 읽기 또는 쓰기 연산
- write(fd, "Test", 5)
- read(fd, buf, 5)
- 파일 닫기
- close(fd)
- 동기화 X → 부모 프로세스가 wait() 함수 사용
3.3 파이프를 이용한 통신
- 파이프는 단방향이기에 양방향 통신을 하려면 파이프르 2개 사용해야 함
종류
- 이름 없는 파이프 : 일반적인 파이프, 서로 관련 있는 프로세스 간 통신에 사용
- 이름 있는 파이프 : FIFO라 불리는 특수 파일을 이용하며 서로 관련 없는 프로세스 간 통신에 사용
3.4 소켓을 이용한 통신
네트워킹 : 여러 컴퓨터에 있는 프로세스 간 통신
- IP(Internet Protocol)
- 목적지까지 데이터를 전송하는 것
- IP 주소는 목적지를 나타냄
- 포트(Port)
- 하나의 컴퓨터 내에서 네트워크를 사용하는 각 프로세스를 구분하는 주소
- TCP가 네트워크를 사용하는 프로세스를 구분하기 위해 사용하는 주소
- 데몬(Daemon)
- 서버에서 돌아가는 프로세스
- 서버용 데몬도 포트 번호가 필요
- 클라이언트가 해당 번호를 매번 찾아야하는데, 이러한 수고를 덜기 위해 중요한 데몬은 미리 정해진 포트 번호를 할당함 (e.g. Http 데몬 : 80, Https 데몬 : 443)
3.5 정리
종류 | 운영체제 동기화 지원 | open()/close() 사용 |
전역 변수 | X (바쁜 대기) | X |
파일 | X (wait() 함수 이용) | O |
파이프 | O | O |
소켓 | O | O |
2. 공유 자원과 임계구역
1. 공유 자원의 접근
공유 자원
여러 프로세스가 공동으로 이용하는 변수, 메모리, 파일 등
경쟁 조건
- 2개 이상의 프로세스가 공유 자원을 병행적으로 읽거나 쓰는 상황
- 공유 자원 접근 순서에 따라 실행 결과가 달라질 수 있음
2. 임계 구역
- 공유 자원 접근 순서에 따라 실행 결과가 달라지는 프로그램의 영역
- 임계구역에서는 프로세스들이 동시에 작업하면 안 됨
3. 생산자-소비자 문제
생산자 프로세스와 소비자 프로세스가 서로 독립적으로 작업하면서 발생하는 문제
- 동시 실행 시 문제 발생
- 생산자와 소비자가 전역 변수 sum에 접근하는 타이밍을 서로 맞추지 않았기 때문
- 하드웨어에서도 일어나는 문제 (ex. 프린터)
4. 임계구역 해결 조건
- 상호 배제 : 한 프로세스가 임계구역에 들어가면 다른 프로세스는 임계구역에 들어갈 수 없다.
- 한정 대기 : 어떤 프로세스도 무한 대기하지 않아야 함
- 진행의 융통성 : 한 프로세스가 다른 프로세스의 진행을 방해해서는 안 됨
3. 임계구역 해결 방법
1. 기본 코드 소개
#include <stdio.h>
typedef enum {false, true} boolean;
extern boolean lock = false;
extern int balance;
main() {
while(lock == true);
lock = true;
balance = balance + 10;
lock = false;
}
2. 임계구역 해결 조건을 고려한 코드 설계
2.1 상호 배제 문제
- lock == true 인 경우 무한 루프 돌면서 대기
- lock == false인 경우 lock을 걸고 임계구역에서 작업한 후 lock을 해제하고 나옴
문제점
- lock == false일 때, lock = true로 걸고 임계구역에 진입해야 하는데 그 직전에 타임아웃이 걸린다면?
- 다른 프로세스도 임계구역에 진입하게 되고, 해당 타임아웃으로 대기하고 있던 프로세스도 대기가 끝나 실행될 대 또 임계구역에 진입해버림
- 동시에 임계구역에 진입할 수 있음
2.2 한정 대기 문제
- 상호 배제 조건은 만족하지만, 타임아웃 타이밍에 따라 상호 무한루프에 빠질 수 있는 위험이 있음
2.3 진행의 융통성 문제
- 상호 배제와 한정 대기 조건 만족
- 만약 P1이 자주 실행되어야 하는 상황이라면?
- P1과 P2는 서로 번갈아가며 실행되어야 하기에 진행의 융통성 조건을 보장하지 못함
2.4 하드웨어적인 해결 방법
3. 피터슨 알고리즘
- 임계구역 해결의 세 가지 조건 모두 만족
- 2개의 프로세스만 사용 가능하다는 한계
4. 데커 알고리즘
- 임계구역 해결의 세 가지 조건 모두 만족
- 2개의 프로세스만 사용 가능하다는 한계
5. 세마포어
프로세스가 작업을 마치면 다음 프로세스에 임계구역을 사용하라는 동기화 신호를 보냄
- Semaphore(n) : 전역변수 RS를 n으로 초기화, n은 현재 사용 가능한 자원의 수
- P() : 잠금을 수행하는 코드
- RS>0이면 (사용 가능한 자원이 있으면) : RS를 1만큼 감소시키고 임계구역 진입
- RS≤0이면 : 0보다 커질 때 까지 block()
- V() : 잠금 해제와 동기화를 같이 수행
- RS 값을 1 증가시킴
- 세마포어에서 기다리는 다른 프로세스에게 wake_up() 신호를 보내 임계구역에 진입해도 좋다는 신호 보냄
BINARY SEMAPHORE
- 초기값이 1
- 상호 배제를 위해 사용 (하나 들어가면 아무도 못들어감)
COUNTING SEMAPHORE
- 초기값이 1 이상
- 한 개 이상의 자원이 있을 때 사용
- 여러 개의 프로세스가 임계구역에 접근 가능
세마포어의 잘못된 사용 예
6. 모니터
- 공유 자원을 내부적으로 숨기고 공유 자원에 접근하기 위한 인터페이스만 제공
- 자원을 보호하고 프로세스 간에 동기화를 시킴
- 임계구역으로 들어가려는 프로세스는 직접 P() 혹은 V()를 사용하지 않음
- 대신 모니터에게 작업을 요청
- 모니터는 요청받은 작업을 모니터 큐에 저장하고 순서대로 처리, 결과만 프로세스에 알려줌
4. 파일, 파이프, 소켓 프로그래밍
1. 파일
1.1 순차 파일
- 파일 내 데이터가 한 줄로 길게 저장
- ex. 카세트 테이프
1.2 파일 기술자(fd)
- 현재 파일에서 어느 위치를 읽고 있는지 가리킴
- 해당 파일에 접근할 수 있는 권한
- 처음에는 파일 맨 앞에 위치
- 파일을 읽거나 쓰면 파일 기술자는 전진함
1.3 파일을 이용한 통신
- 부모 프로세스가 자식 프로세스보다 먼저 실행되면 자식 프로세스가 아무 작업도 하지 않으므로 빈 내용을 읽게 됨
- 따라서 부모-자식 프로세스 간 동기화 필수
- 부모 프로세스는 wait() 함수를 통해 자식 프로세스가 끝나기를 기다림
- fork() 이전에 파일을 open()하면 생성된 fd가 자식 프로세스에도 상속됨
- 자식 프로세스도 파일 접근 가능
- 한 fd를 공유함
- open() 1번 close() 두 번
- 자식 프로세스가 작업이 끝나면 lseek()을 통해 fd를 맨 앞으로 보냄
- 동기화 X
- 파일에서는 fd를 공유하므로 read(), write() 상관 없이 fd가 전진하므로 동기화 불가
2. 파이프
- 부모-자식과 같이 서로 연관된 프로세스 통신에 사용
- read(), write()의 기술자가 따로 존재함
- fork() 발생 시 총 4개의 기술자 존재
- 단방향 통신이므로 프로세스당 1개의 기술자만 사용
- 필요없는 기술자는 닫아버림
- 대기가 있는 통신이므로 wait()가 필요 X
- 부모 프로세스가 먼저 실행되면 파이프에 메시지가 들어올 때 까지 대기상태
3. 네트워킹
- 클라이언트 통신 절차
- 클라이언트는 소켓을 생성하고 connect() 를 사용하여 서버와의 접속 시도
- 서버와 접속되면 read()/write() 작업 수행
- 작업이 끝나면 사용한 소켓 기술자를 닫고 종료
- 서버 통신 절차
- 서버는 소켓을 생성하고 bind()를 사용하여 생성한 소켓을 특정 포트에 등록 (하나의 포트에 여러 개의 소켓을 생성)
- 소켓이 정상적으로 등록되면 listen() 을 실행하여 클라이언트를 받을 준비를 함
- 클라이언트를 받으면 accept() 를 실행하여 소켓 기술자를 생성 후 작업 수행
'CS Study > 쉽게 배우는 운영체제' 카테고리의 다른 글
[OS] Ch.6 교착상태 (0) | 2024.02.29 |
---|---|
[OS] 쉽게 배우는 운영체제 5장 연습문제/심화문제 (0) | 2024.02.29 |
[OS] 쉽게 배우는 운영체제 4장 연습문제/심화문제 (0) | 2024.02.15 |
[OS] Ch.4 CPU 스케줄링 (0) | 2024.02.15 |
[OS] 쉽게 배우는 운영체제 3장 연습문제/심화문제 (0) | 2024.02.15 |