코딩하는 둥둥

[ 쉽게 배우는 운영체제 ] 5-1. 프로세스 동기화 본문

Computer Science/쉽게 배우는 운영체제

[ 쉽게 배우는 운영체제 ] 5-1. 프로세스 동기화

둥둥 2022. 8. 3. 00:55
728x90

프로세스 간 통신의 개념

프로세스가 다른 프로세스와 데이터를 주고받는 프로세스 간 통신 IPC에는 같은 컴퓨터 내에 있는 프로세스뿐만 아니라 네트워크로 연결된 다른 컴퓨터에 있는 프로세스와의 통신도 포함된다.

 

전역 변수나 파일을 사용하여 통신하는 것은 운영체제의 도움 없이 진행되는 통신 방식이며 파이프, 소켓, 원격 프로시저 호출(Remote Procedure Call; RPC)은 운영체제가 제공하는 통신 방식이다. 

 

  • 프로세스 내부 데이터 통신 : 하나의 프로세스 내에 2개 이상의 스레드가 존재하는 경우의 통신으로 프로세스 내부의 스레드는 전역 변수나 파일을 이용하여 데이터를 주고받는다.
  • 프로세스 간 데이터 통신 : 같은 컴퓨터에 있는 여러 프로세스끼리 통신하는 경우로, 공용 파일 또는 운영체제가 제공하는 파이프를 사용하여 통신한다.
  • 네트워크를 이용한 데이터 통신 : 여러 컴퓨터가 네트워크로 연결되어있을 때도 통신이 가능한데, 이 경우 프로세스는 소켓을 이용하여 데이터를 주고받는다. 다른 컴퓨터에 있는 함수를 호출하여 통신하는 원격 프로시저 호출도 여기에 해당한다.
어떤 통신 방식을 이용할지 결정할 때는 오버헤드를 고려해야 한다.
예를 들어 같은 컴퓨터에 있는 프로세스끼리도 소켓을 이용해 통신할 수 있다. IP주소로 127.0.0.1과 같이 루프백 주소를 사용하면 되지만 소켓을 사용하려면 많은 전처리를 해야 하기 때문에 다른 프로세스가 통신 방법보다 느리다. 따라서 같은 컴퓨터에 있는 프로세스 간 통신에는 소켓을 거의 사용하지 않는다.

 

프로세스 간 통신은 데이터를 주거나 send 받는 receive 단순한 통신 방법을 가지고 있다. 


프로세스 간 통신의 분류

통신 방향에 따른 분류

프로세스 간 통신은 동시에 실행되는 프로세스끼리 데이터를 주고받는 작업을 의미한다. 

  • 양방향 통신 duplex communication : 데이터를 동시에 양쪽 방향으로 전송할 수 있는 구조로, 일반적인 통신을 말한다. 프로세스 간 통신에서는 소켓 통신이 이에 해당한다. 
  • 반양방향 통신 half-duplex communication : 데이터를 양쪽 방향으로 전송할 수 있지만 동시 전송은 불가능하고 특정 시점에 한쪽 방향으로만 전송할 수 있는 구조이다. 대표적인 예로 무전기가 있다.
  • 단방향 통신 simplex communication : 모스 신호처럼 한쪽 방향으로만 데이터를 전송할 수 있는 구조이다. 프로세스 간 통신에서는 전역 변수와 파이프가 이에 해당한다.

대부분의 통신은 양방향 통신이지만 전역 변수는 단방향 통신이다. 따라서 전역 변수가 1개이면 한쪽 방향으로만 통신이 가능하며, 양방향 통신을 구현하려면 전역 변수를 2개 사용해야 한다.

 

통신 구현 방식에 따른 분류

전역 변수를 사용하는 통신 방식의 경우 데이터를 받는 쪽에서 언제 데이터를 받을 수 있을지 모른다는 문제가 있다. 따라서 데이터를 받는 쪽에서는 반복적으로 전역 변수의 값을 점검해야 한다.

상태변화를 살펴보기 위해 반복문을 무한 실행하며 기다리는 것을 바쁜대기 busy waiting라고하며, 시스템 차원에서 큰 자원 낭비이다. 

 

이러한 문제를 해결하기 위해 데이터가 도착했음을 알려주는 동기화를 사용한다. 

프로세스 간 통신은 동기화 기능이 있느냐 없느냐에 따라 구분된다.

 

  • 대기가 있는 통신 blocking communication : 동기화를 지원하는 통신 방식으로, 데이터를 받는 쪽은 데이터가 도착할 때까지 자동으로 대기상태에 머물러있다.
  • 대기가 없는 통신 non-blocking communication : 동기화를 지원하지 않는 통신방식으로 데이터를 받는 쪽은 바쁜 대기를 사용하여 데이터가 도착했는지 여부를 직접 확인한다.

전역 변수와 파일을 이용한 통신은 대기가 없는 통신의 대표적인 예로, 대기가 없는 통신은 오버헤드는 적지만 바쁜 대기처럼 사용자가 직접 처리해야 하는 작업이 많다.


프로세스 간 통신의 구조

프로세스 간 통신은 데이터를 주거나 받는 동작으로 이루어지며 쓰기 연산과 읽기 연산으로 간소화할 수 있다.

이러한 프로세스 간 통신 방식은 전역 변수뿐만 아니라 파일, 파이프, 소켓을 이용한 통신에도 동일하게 적용된다.

 

전역 변수를 이용한 통신

전역 변수를 이용한 통신은 공동으로 관리하는 메모리를 사용하여 데이터를 주고받는 것이다. 데이터를 보내는 쪽에서는 전역 변수나 파일에 값을 쓰고, 데이터를 받는 쪽에서는 전역 변수의 값을 읽는다. 전역 변수를 이용한 통신방법은 주로 직접적으로 관련이 있는 프로세스 간에 사용한다.

 

파일을 이용한 통신 

파일 입출력 코드는 파일을 열고 open 쓰고 write 읽는 read 세 부분으로 이루어져 있으며 위 작업이 끝난 후 파일을 닫는다 close.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
 
int main()
{    int fd;
    char buf[5];
 
    fd=open("com.txt", O_RDWR); // com.txt를 읽기/쓰기 전용으로 연다 
                                // * O_RDWR : 파일을 읽기/쓰기용으로 연다
    
    write(fd, "Test"5); // 하드디스크로 comt.txt파일에 Test 문자열 쓰기
                          /* Test의 크기가 5B이기때문에 5라고 명시
                            (문자열의 끝을 알리는 특수부호 null포함하기때문에 5B) */                                      
    
    read(fd, buf, 5); // com.txt파일에서 5B를 읽어 변수 buf에 저장
 
    close(fd); // 파일 종료
 
    exit(0);
}
 
cs
  • 파일 열기 : open() 함수를 이용하여 사용하고자 하는 파일이 있는지, 그 파일에 쓰기 권한이 있는지 확인한다. 정상적으로 사용할 수 있다면 open() 함수는 fd를 반환한다. fd는 어떤 파일에 접근할 수 있는 권한으로 파일 기술자(file descriptor)라고도 불린다. 어떤 파일에 읽기나 쓰기 연산을 하려면 먼저 얻어야 하며, 작업이 끝나면 돌려주어야 한다. 파일을 연 이후에는 파일 기술자를 통해서만 접근 가능하다.
  • 읽기 또는 쓰기 연산 : fd는 해당 파일에 대한 접근 권한을 가지고 있기 때문에 쓰기나 읽기 연산의 맨 앞에는 언제나 fd를 사용한다.
  • 파일 닫기 : close 함수를 이용해 파일을 닫는다.

파일을 이용한 통신은 부모-자식 관계 프로세스 간 통신에 많이 사용되며 운영체제가 프로세스 동기화를 제공하지 않아 알아서 동기화를 해야 한다. 주로 부모 프로세스가 wait() 함수를 이용해 자식 프로세스의 작업이 끝날 때까지 기다렸다가 작업을 시작한다.

 

파이프를 이용한 통신

파이프는 운영체제가 제공하는 동기화 통신 방법으로, 파일 입출력과 같이 open() 함수로 기술자를 얻고 작업을 한 후 close() 함수로 마무리한다. 전역 변수를 이용한 통신과 마찬가지로 단방향 통신이며, 파이프로 양방향 통신을 하려면 파이프 2개를 사용해야 한다.

 

  • 이름 없는 파이프 anonymous pipe : 일반적인 파이프로, 부모와 자식 프로세스 혹은 같은 부모를 가진 자식 프로세스와 같이 서로 관련 있는 프로세스 간 통신에 사용된다.
  • 이름 있는 파이프 named pipe : FIFO라 불리는 특수파일을 이용하며 서로 관련 없는 프로세스 간 통신에 사용된다.

 

소켓을 이용한 통신

여러 컴퓨터에 있는 프로세스 간 통신은 네트워킹이라고 하는데 이때 원격 프로시저 호출이나 소켓을 이용한다.

원격 프로시저 호출은 다른 컴퓨터에 있는 함수를 호출하는 것이다. 

자바 같은 객체 지향 언어에서 다른 컴퓨터에 있는 객체의 메서드를 불러와 사용하는 것은 모두 원격 프로시저 호출의 예이다.

 

일반적으로 원격 프로시저 호출은 소켓을 이용하여 구현한다. 다른 컴퓨터에 있는 프로세스와 통신을 하려면 그 컴퓨터의 위치를 파악하고, 원격지의 시스템 내 여러 프로세스 중 어떤 프로세스와 통신을 할 지도 결정해야 한다.

 

소켓은 프로세스 동기화를 지원하므로 데이터를 받는 쪽의 프로세스가 바쁜 대기를 하지 않아도 된다. 


종류 운영체제 동기화 지원 open()/close() 사용
전역 변수 X(바쁜 대기) X
파일 X(Wait() 함수 이용) O
파이프 O O
소켓 O O

 

728x90