프로세스 동기화

컴공생의 코딩 일기·2023년 4월 27일
0

운영체제

목록 보기
3/9

프로세스 간 통신

프로세스 간 통신의 개념

운영체제는 프로세스와 프로세스끼리 쉽게 데이터를 주고 받을 수 있는 통신 방법을 제공하는데 이를 프로세스 간 통신(IPC; Inter Process Communication) 이라고 한다.

  • 공유 메모리나 공유 파일을 이용한 통신: 일정한 메모리 영역이나 파일을 공유하고 이를 통하여 데이터를 주고 받는다.
  • 파이프를 이용한 통신: 파이프는 프로세스 간 통신을 위하여 운영체제가 제공하는 통신 기법이다.
    • 보통의 경우에 파이프는 fork()로 만들어진 부모-자식 간 통신에 사용된다.
    • 하나의 컴퓨터 내에서 프로세스 간 통신에 많이 사용되는 수단이다.
  • 소켓을 이용한 통신: 네트워크로 연결된 컴퓨터에서 데이터를 주고받기 위한 통신 기법이다.
    • 컴퓨터와 컴퓨터가 네트워크로 연결된 경우의 통신에 주로 사용된다.

통신을 단순하게 보면 데이터를 주거나(send) 받는(receive) 것이다. 데이터를 보내는 프로세스는 send(message)를 사용하고 데이터를 받는 쪽은 receive(message)를 사용한다.

프로세스 간 통신의 분류

  • 양방향 통신:
    • 데이터를 양쪽 방향으로 동시에 전송할 수 있는 구조
    • 일반적인 통신은 모두 양방향 통신이다.
    • 예) (프로세스간 통신) 소켓
    • 예) (통신 기기) 전화
  • 반양방향 통신:
    • 데이터를 양쪽 방향으로 전송할 수 있지만 동시 전송은 불가능하고 특정 시점에 한쪽 방향으로만 전송할 수 있는 구조
    • 예) 무전기
  • 단방향 통신:
    • 모스 부호처럼 한쪽 방향으로만 데이터를 전송할 수 있는 구조
    • 단방향 통신에서 양방향 통신을 구현하고 싶다면 공유 메모리(공유 메모리를 사용할 경우, 파이프를 사용할 경우 파이프를 2개 사용해야 함)를 2개 사용해야 한다.
    • 예) (프로세스간 통신) 공유메모리나 공유 파일, 파이프
    • 예) (통신 기기) 모스 부호

공유 메모리의 문제점

공유 메모리 문제점은 상대방이 데이터를 언제 보낼지 받는 쪽은 모른다. 받는 쪽에서는 공유 메모리를 반복적으로 점검해야 한다. 이를 바쁜 대기(busy waiting) 이라고 한다.(상태 변화를 살펴보기 위해 반복문을 무한 실행하며 기다리는 것)

공유 메모리의 문제점 해결 방법

  • 동기화(synchronization) 사용
    • 예) 메신저에서 메시지가 도착했다고 알려주는 알림

프로세스 간 통신은 동기화 기능이 있느냐 없느냐의 따라 대기가 있는 통신(bloking communication)과 대기가 없는 통신(non-blocking communication) 으로 구분한다.
대기가 있는 통신을 동기화 통신(synchronous communication), 대기가 없는 통신을 비동기화 통신(asynchronous communication) 이라고 한다.

종류통신 기법통신 기기
대기가 있는 통신(동기화 통신)파이프, 소켓전화
대기가 없는 통신(비동기화 통신)공유메모리, 공유 파일전보

프로세스 간 통신의 종류

  • 파일 입출려 코드: 열고(open), 쓰기(write) 또는 읽기(read), 닫기(close)
    • open() : 파일을 사용하기 위한 준비 단계
      • open("파일명", 작업);
        • 작업: O_RDWR (읽기와 쓰기), O_RDONLY (읽기 전용)
        • 예) open("com.txt", O_RDWR)
      • write(접근권한(onpen으로 부터 전달된 변수), 내용, 바이트 수)
        • 예) write(fd, "Test", 5)
      • read(접근권한(onpen으로 부터 전달된 변수), 저장할 변수, 바이트(
        • 예) read(fd, buf, 5)
    • close(): 함수를 이용하여 파일을 닫는다.
      • 예) close(fd): fd가 가리키는 파일, 즉 com.txt 파일을 닫는다.

읽기 쓰기는 하드디스크에 데이터 전송 데이터 가져오기 명령이라 할 수 있으므로 파일 입출력도 통신(운영체제 입장에서는 일반 프로세스와 입출력 프로세스 간의 통신)이다.

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

파이프를 이용한 통신

파이프는 운영체제가 제공하는 동기화 통신 방식으로 파일 입출력과 같이 open() 함수로 기술자를 얻어 작업한 후 close() 함수로 마무리한다.

  • 파이프는 단방향 통신으로 양방향 통신을 하려면 파이프를 2개를 사용해야 한다.

  • 이름 없는 파이프: 부모와 자식 프로세스 혹은 같은 부모를 가진 자식 프로세스와 같이 서로 관련 있는 프로세스 간 통신에 사용

  • 이름 있는 파이프: FIFO라 불리는 특수 파일을 이용하며 서로 관련 없는 프로세스 간 통신에 사용된다.

소켓을 이용한 통신

  • 여러 컴퓨터에 있는 프로세스 끼리 통신할 때(네트워킹) 소켓을 사용
  • 하나의 포트에 여러 클라이언트를 연결하려면 소켓(socket)이 필요하다.
  • 소켓은 프로세스 동기화를 지원 (데이터를 받는 쪽의 프로세스가 바쁜 대기를 하지 않아도 된다.)
  • 양방향 통신 가능

공유 자원과 임계구역

공유 자원에 대한 접근

공유자원(shared resource)은 여러 프로세스가 공동으로 이용하는 변수, 메모리, 파일등을 말한다. 공유 자원은 공동으로 이용되기 때문에 누가 언제 데이터를 읽거나 쓰느냐에 따라 그 결과가 달라질 수 있다. 2개 이상의 프로세스가 공유 자원을 병행해서 읽거나 쓰는 상황을 경쟁 조건(race condition)이 발생했다고 한다.

임계구역

공유 자원 접근 순서에 따라 실행 결과가 달라지는 프로그램의 영역을 임계구역(critical section)이라고 한다. 임계구역에서는 프로세스들이 동시에 작업하면 안 된다.

생상자-소비자 문제

임계구역과 전통적인 문제로 생산자-소비자 문제(producer-consumer problem)가 있다. 이 문제에서는 생산자 프로세스와 소비자 프로세스가 서로 독립적으로 작업한다.

임계구역 문제 해결 조건

  • 상호 배제(mutual exclusion): 한 프로세스가 임계구역에 들어가면 다른 프로세스는 임계구역에 들어갈 수 없다.
  • 한정 대기(bounded waiting): 어떤 프로세스가 임계구역에 진입하지 못하여 무한 대기(infinite postpone) 하지 않아야 한다.
  • 진행의 융통성(progress flexibility): 한 프로세스가 다른 프로세스의 진행을 방해해서는 안된다는 것을 의미한다.

임계구역 문제 해결 방법

임계구역 문제를 해결하는 단순한 방법은 잠금 lock을 이용하는 것이다.

상호배제 문제

  1. 프로세스 P1과 P2는 임계구역에 진입하기 전에 임계구역에 잠금이 걸려있는지 확인(lock == true)

  2. 잠겨있는 경우 잠금이 해제될 때 까지 무한 루프를 돌면서 대기[while(lock == true);]

  3. 임계구역에 있는 프로세스가 작업을 마치고 잠금을 해제하면(lock = false;) 루프에서 빠져나와 작업

  4. 새로 임계구역에 진입하는 프로세스는 잠금을 걸고(lock = true;) 작업

  5. 작업을 마치면 다른 프로세스가 사용할 수 있도록 잠금 해제(lock = false;)

문제 상황

프로세스 P1이 while(lock == true)문을 통과하고 lock=true 만나기 전에 주어지 CPU 시간이 다 써서(타임아웃) 준비 상태로 돌아가고 문맥교환이 발생하고 P2가 실행상태로 바뀌면 P2는 lock이 true이기 때문에 P2 또한 임계구역에 진입할 수 있는 문제가 생긴다.

한정 대기 문제

  • 잠금을(lock)을 두 개 사용한다
  • 일단 잠금을 설정하고 다른 프로세스도 잠갔는지 확인하므로 두 프로세스의 상호 배제가 보장된다.

문제 상황

프로세스 P1과 P2 모두 lock1 = true, lock2 = true 문을 실행한 후 타임 아웃이 걸리면 둘 다 무한 루프에 빠지게 된다. 이를 교착 상태(deadlock)라고 한다. 교착상태는 프로세스가 살아 있으나 작업을 진행되지 못하는 상태다.

위에 코드는 프로세스가 3개라면 lock 도 3개로 늘어나기 때문에 확장성 문제도 가지고 있다.

진행의 융통성 문제

  • int lock: 1이면 프로세스 P1이 임계구역 사용, 2면 프로세스 P2가 임계구역 사용

문제 상황

위에 코드는 잠금을 확인하는 문장이 하나 이므로 상호 배제와 한정 대기를 보장한다. 하지만 한 프로세스가 두 번 연달아 임계구역을 사용하지 못하고 서로 번갈아가면서 실행되는 문제가 있다. 이렇게 프로세스의 진행이 다른 프로세스의 로 인해 방해받는 현상을 경직된 동기화(lockstep synchronization)라고 한다.

하드웨어로 해결 방법


상호 배제 문제에서 하드웨어로 두 명령어를 동시에 실행하면 임계구역 문제를 쉽게 해결할 수 있다.
왼쪽 코드의 1~2행은 오른쪽 코드의 1행과 같다. 이는 검사와 지정(test-and-set) 이라는 코드로 하드웨어의 지원을 받아 while(lock==true) 문과 lock=true 문을 한꺼번에 실행한 것이다.

임계구역을 하드웨어로 사용하면 바쁜 대기를 사용하여 검사하기 때문에 자원 낭비가 발생한다.

피터슨 알고리즘


피터슨 알고리즘은 turn이라는 변수를 하나 사용해서 두 프로세스가 lock을 설정하여 임계구역을 못 들어가는 상황을 대비하기 위한 장치다.
피터슨 알고리즘은 세가지 조건을 모두 만족하지만 2개의 프로세스만 사용 가능하다는 단점이 있다.

데커 알고리즘

  1. 프로세스 P1은 우선 잠금을 건다(lock1=true).
  2. 프로세스 P2의 잠금이 걸렸는지 확인한다[while(lock2==true)].
  3. 만약 프로세스 P2도 잠금을 걸었다면 누가 먼저인지 확인한다[if (turn==2)]. 만약 프로세스 P1의 차례라면(turn==1) 임계구역으로 진입하고 프로세스 P2의 차례라면(turn==2) 4로 이 동한다.
  4. 프로세스 P1은 잠금을 풀고(lock1=false) 프로세스 P2가 작업을 마칠 때까지 기다린다 [while(turn==2)]. 프로세스 P2가 작업을 마치면 잠금을 걸고(lock1=true) 임계구역으로 진입한다.

테커 알고리즘은 세가지 조건을 모두 만족하지만 너무 복잡하다.

세마포어

  • Semaphore(n): 전역 변수 RS를 n으로 초기화한다. Rs에는 현재 사용 가능한 자원의 수가 저장된다.
  • P(): 잠금을 수행하는 코드로, RS가 0보다 크면(사용 가능한 자원이 있으면) 1만큼 감소시키고 임계구역에 진입한다. 만약 RS가 0보다 작으면(사용 가능한 자원이 없으면) 0보다 커질 때까지 기다린다. block()은 wake_up() 이 신호를 보낼 때까지 가다리는 함수이다.
  • V(): 잠금 해제와 동기화를 같이 수행하는 코드로, RS 값을 1 증가시키고 기다리는 프로세스에 임계구역에 진입해도 좋다는 wake_up() 신호를 보낸다.

세마포어의 P()나 V() 내부 코드가 실행되는 도중에 다른 코드가 실행되면 상호 배제와 한정 대기 조건을 보장하지 못한다. 그러므로 P()와 V()의 내부 코드는 검사와 지정을 사용하여 완전히 실행되도록 구현된다.

모니터

모니터는 공유 자원을 내부적으로 숨기고 공유 자원에 접근하기 위한 인터페이스만 제공함으로써 자원을 보호하고 프로세스 간에 동기화시킨다.
모니터는 시스템 호출과 같은 개념이다.

1. 임계구역으로 지정된 변수나 자원에 접근하고자 하는 프로세스는 직접P()나 V()를 사용하지 않고 모니터에 작업 요청을 한다.
2. 모니터는 요청받은 작업을 모니터 큐에 저장한 후 순서대로 처리하고 그 결과만 해당 프로세스에 알려준다.

profile
더 좋은 개발자가 되기위한 과정

0개의 댓글