TIL - 2020.11.26 (목)

코드 굽는 제빵사·2020년 12월 2일
0

TIL

목록 보기
7/20
post-thumbnail

리눅스 커널 디자인의 기술을 읽으면서 책 내용 정리하기 (티스토리부터 이전 된 자료 입니다.)

IPC (프로세스 간 통신)

리눅스 0.11에서 프로세스는 프로세스 경계를 임의로 넘어서 다른 프로세스의 코드나 데이터에 접근 할 수 없다. 이것은 운영체제가 시스템을 보호하기 위한 중요한 기능이다. 하지만 현실적으로 프로세스들이 서로 협력하고 때로는 서로의 정보를 공유해야 한다. 문제는 프로세의 코드와 데이터를 보호하면서 프로세스 간 통신을 어떻게 할 수 있느냐 하는 것이다. 리눅스 0.11 운영체제는 이런 요구 사항에 부합하기 위해 두 가지 메커니즘을 제공한다. 하나는 파이프 메커니즘이고, 다른 하나는 시그널 메커니즘이다.

파이프 메커니즘

파이프는 두 프로세스 간 데이터를 상호 교환할 수 있게 한다. 한쪽 프로세스가 데이터를 파이프에 넣으면 다른 쪽 프로세스가 파이프에서 데이터를 꺼낸다. 이 방법을 사용하면 프로세스 간 통신을 할 수 있으면서도 프로세스의 경계를 침범하지 않아도 된다.

운영체제는 각 파이프에 한 페이지의 메모리를 할당한다. 그리고 이 메모리에 파일 속성을 부여한다. 메인 메모리에 할당된 이 메모리는 두 프로세스에 공유되지만 어떤 프로세스에도 속하지 않는다. 오직 커널만이 이 메모리를 제어한다.

파이프 생성 과정

파이프에 사용되는 메모리는 파일 속성은 추가하고, 메모리 속성은 제거된다.
메모리 속성을 제거한다는 의미는 결국 메모리 페이지가 파일처럼 사용 되어야 한다는 것이다. 예를 들어 프로세스는 유저 영역의 데이터에 접근하는 것처럼 파이프를 사용 할 수 없다. 이것은 파이프 메모리를 프로세스 메모리 공간에 맵핑하지 않기 때문이다. 다른 예로 메모리 페이지를 다루는 두 개의 프로세스가 있다고 가정한다. 이들은 한 쪽에서 데이터를 쓰고 있으면 다른 한쪽에는 데이터를 읽는다. 이때 쓰기에 의한 페이지 폴트가 발생하지 않는다. (파이프에 할당되는 메모리 영역을 벗어나면 다시 처음으로 롤백되어 쓰이기 때문) 또 파이프는 공유할 수도 없다.

파이프 동작

리눅스 0.11의 파이프 동작 방식은 다음과 같다. 파이프에 아직 읽지 않은 데이터가 남아 있을 때 읽기를 하면 반드시 데이터를 읽을 수 있다. 하지만 읽을 데이터가 없을 때 파이프를 읽으면 동작이 멈춘다. 즉 한번 읽힌 데이터는 다시 읽히지 않는다. 파이프에 쓰기를 하는 과정에서 파이프에 데이터를 쓸 여유 공간이 있다면 쓰기 동작이 수행되지만, 쓸 수 있는 공간이 없으면 쓰기 과정은 중단된다. 즉 읽히지 않은 데이터가 다른 데이터에 덮여 없어지지 않는다. 또 파이피의 크기는 메모리 한 페이지와 동일하다.

메모리 한 페이지는 보통 4KB이다.

파이프를 읽는 프로세스가 먼저 실행된다. 시스템이 파이프를 읽으려고 하지만 파이프에 어떤 데이터도 없다.
시스템은 이 프로세스를 서스펜드시키고 파이프에 데이터를 쓰는 프로세스를 실행되도록 한다. 프로세스가 파이프에 데이터를 쓰고나면 파이프에는 읽을 수 있는 데이터가 생겨 대기 상태로 있던 파이프 읽기 프로세스가 깨어난다.

시그널 메커니즘

리눅스 0.11에서 프로세스에게 제공하는 인터럽트 유사 메커니즘이다. 프로세스 실행중에, 프로세스가 시그널을 받았다는 것을 시스템이 인지하면, 시스템은 프로세스의 실행을 잠시 중지시키고 프로세의 시그널 처리 핸들러를 실행시킨다. 핸들러 수행이 끝나면 중지되었던 위치에서 다시 시작된다.

1. 시스템은 시그널을 보내고 받는 방법을 제공해야 한다.

시스템은 프로세스의 task_struct에 있는 signal 필드를 이용해서 프로세스가 시그널을 받았는지 기록한다. 시스템은 프로세스에 시그널을 보내기 위해 두 가지 방법을 제공한다. 한가지 방법은 프로세스에서 다른 프로세스로 시그널을 보내기 위해서 특별한 라이브러리 함수를 호출하는 방법이고, 다른 방법은 사용자가 키보드를 입력하면 발생하는 키보드 인터럽트를 이용해서 인터럽스 서비스 루틴 내에서 프로세스에 시그널을 보내는 방법이다.

2. 시스템은 프로세스가 시그널을 받으면 감지할 수 있어야 한다.

프로세스가 시그널을 받았는지 감지할 수 있는 두가지 방법이 있다. 하나는 시스템 콜에서 반환하기 전에 시그널을 받았는지 확인하는 것이다. 또 다른 방법은 타이머 인터럽트가 발생했을 때 인터럽트 서비스 루틴이 끝나기전에 현재 프로세스가 시그널을 받았느지 확인하는 방법이다.

3. 시스템은 시그널을 처라할 수 있는 절차를 지원해야 한다.

유저 프로세스가 시그널을 처리하지 않았을 때, 시그널 처리 함수가 유저 프로세스에 영향을 주어서는 안된다.
반면 유저 프로세스가 시그널을 처리해야 할 때, 프로세스의 프로그램을 잠시 중단시키고 시그널 처리 함수를 실행할 수 있도록 시스템이 지원해야 한다. 그리고 시그널 처리 함수가 끝나면 프로세스가 멈췄던 위치로 돌아가 다시 실행되도록 해야 한다.

0개의 댓글

관련 채용 정보