본문 바로가기

지식/system

프로그램 입출력 (Programmed IO)

5.2.2 프로그램 입출력


입출력을 실행하는 방법으로 세가지 기본적인 방법이 있다. 프로그램 입출력, 인터럽트 구동,


DMA(Direct Memory Access)를 이용한 입출력이 있는데, 그 중 가장 간단한 형태인 프로그램


입출력(Programmed IO)에 대해 알아보자. 이는 입출력에 대한 작업을 CPU가 모두 처리해야


하는 방식으로 CPU 오버헤드(Overhead)가 크다는 단점이 있다. 다음의 예를 보자.



사용자 프로세스가 'ABCDEFGH'라는 여덟개의 문자열을 프린터에 출력한다고 가정해보자.

먼저 그림 1.(a)에서 보는 바와 같이 사용자 영역의 버퍼에 문자열을 모은다.

사용자 프로세스는 쓰기를 하기 위해 오픈(open())하라는 시스템 호출을 통해 프린터의 권한을

취득하게 된다. 만약 현재 다른 프로세스가 사용하고 있다면 이 호출은 실패해서 오류코드를 돌

려보내거나 프린터를 사용할 수 있을 때까지 정지되게 된다. 어떻게 행동하느냐는 운영체제와

호출 시 사용되는 파라미터에 따라 달라진다. 일단 프린터를 취득하게 되면 사용자 프로세스는


운영체제에게 문자열을 프린터에 출력하라는 시스템 호출을 하게 된다. 그런 후 일반적으로 버

퍼 내의 문자열을 더욱 편리하게 접근할 수 있는 커널 영역(사용자 영역을 접근하기 위해서는

메모리 맵(Memory Map)을 변경해야 하는 경우가 있기 때문)의 배열, 예를 들어 배열 'p'

복사하게 된다. 그 다음, 현재 프린터가 사용가능한 지 확인한다. 사용할 수 없으면 가능해질

때까지 기다린다. 사용이 가능해지면 운영체제는 메모리 맵 입출력을 사용하여 첫 문자를 프린

터의 데이터 레지스터로 복사한다. 이 행위가 프린터를 작동시킨다. 어떤 프린터들은 라인이나

페이지 단위로 버퍼를 하기 때문에 문자가 아직 나타나지 않을 수도 있다. 그러나 그림 1.(b)에

서는 첫 문자가 출력되고 시스템이 문자 'B'를 출력될 다음 문자로 표시해 놓고 있음을 볼 수

있다. 첫 문자를 프린터로 복사하자마자 운영체제는 프린터가 다음 문자를 받을 준비가 되어


있는 지를 확인한다. 일반적으로 프린터는 그의 상태를 알려주는 두번째 레지스터를 갖고 있

다. 데이터 레지스터로의 쓰기 행위는 준비되지 않은 상태로 만들게 된다. 프린터 제어기가 현

재의 문자 처리를 완료하게 되면 이의 준비된 상태를 나타내기 위해 상태 레지스터의 특정 비

트를 세팅하거나 특정 값을 저장한다. 이 시점에서 운영체제는 프린터가 다시 준비된 상태로


돌아오길 기다린다. 돌아오게 되면, 그림 1.(c)에서 보는 바와 같이 다음 문자를 출력한다. 모

든 문자들이 출력될 때까지 이 루프(loop)는 반복된다. 완료가 되면 제어권은 사용자 프로세스

에게로 다시 돌아간다.


----- 프로그램 입출력을 이용해서 프린터에 문자열 쓰기 -----

copy_from_user(buffer, p, count);                 /* p is the kernel buffer */

or(i = 0; i < count; i++) {                             /* loop on every character */

    while (*printer_status_reg != READY);       /* loop until ready */

    *printer_data_register = p[i];                    /* output one character */

}

return_to_user();

---------------------------------------------------------


운영체제가 하는 행동을 위에 요약하였다. 첫째 데이터가 커널로 복사된다. 그리고 운영체제는


한 문자씩 출력하는 루프에 들어간다. 위에서 보는 것처럼 프로그램 입출력의 가장 중요한 면은


한 문자를 출력한 후에 CPU가 장치에게 다음 문자를 받을 준비가 되어 있는 지를 계속해


서 문 의한다는 사실이다. 이러한 행위를 흔히 폴링(polling) 또는 바쁜 대기(busy

 

waiting)라고 한다. 프로그램 입출력은 간단하지만 입출력이 완료될 때까지 CPU를 완전하게


차지한다는 단점이 있다. 만약에 문자를 출력하는 시간이 아주 짧다면(실제로 프린터가 하는


일은 새로운 문자를 내부 버퍼로 복사하는 일 뿐이므로), 폴링 방식을 써도 좋다. 그러나


CPU가 다른 일을 해야 하는 좀 더 복잡한 시스템에서 폴링 방식은 비효율적이다.