입력, 출력은 프로그램에게 있어 필수적인 개념이다. 우리가 프로그램을 만드는 이유가 무엇인가? 프로그램에게 어떤 입력을 넣으면 이런저런 연산 이후 우리가 원하던 결과를 출력해주기를 원하기 때문이다. Input/Output 개념은 프로그래밍에 있어서 필수적으로 확실히 알아야 하는 개념이다.
프로세스는 어떻게 유저로부터 들어오는 input을 읽거나 output을 출력할 수 있는 것일까? 이를 알기 위해서는 file descriptor에 대한 이해가 필요하다.
File descriptor을 이해하기 위해서는 먼저 data stream을 이해해야 할 필요가 있다.
data stream은 input, output 과정에서 발생하는 데이터의 흐름을 추상화한 것이다. 더 쉽게 표현하자면, 프로그램으로 들어가거나(input) 프로그램으로부터 나오는(output) 데이터의 이동통로를 data stream이라고 말한다. 실제 data stream은 OS에서 관리하며 각 data stream의 buffer를 이용하여 데이터를 주고받는다. 유저로부터 키보드를 통해 입력을 받는 stdin과 프로그램이 결과를 모니터로 출력하는 stdout이 대표적인 data stream이다.
File descriptor table은 앞서 설명한 data stream을 저장하고 있는 일종의 array이다.
하나의 프로세스는 여러가지 IO stream을 가질 수 있다. 일단 기본적으로 stdin, stdout, stderr가 있고 파일과 데이터를 주고받을 수도 있고 네트워크 소켓을 통해 다른 기기로부터 데이터를 주고받을 수도 있다. 이 IO stream들을 모아 하나의 array로 관리하는 것이 file descriptor table이다. File descriptor table은 프로세스별로 하나씩 존재하며 OS 커널에서 관리한다.
앞서 IO stream과 file descriptor table에 대해 알아보았다. 그럼 이제 file descriptor가 무엇인지 알 수 있다.
File descriptor는 file descriptor table에 존재하는 IO stream의 index이다. 프로세스는 어떻게 IO stream에 접근할 수 있을까? 앞서 설명했듯이 file descriptor table은 IO stream을 담고있는 배열로 각 IO stream을 index를 통해 접근할 수 있다. 우리는 이 index를 file descriptor라고 한다. 즉, file descriptor는 간단한 integer 정수인 index이다. IO stream 객체 같은 어려운 개념이 아니다.
그렇다면 file descriptor을 배운 상태에서 파이썬에서 input을 어떤 식으로 다루는지 생각해보자.
파이썬에서는 대표적으로 standard input을 받는 방법이 stdin을 이용한 방법과 input()을 이용한 방법 2가지가 있다. 각 방법의 특징에 대해 알아보자.
import sys
myinput = sys.stdin.readline()
sys 라이브러리에 존재하는 standard input 객체이다. 앞서 설명한 file descriptor 0번에 해당하는 standard input을 사용해 유저의 입력을 받는다.
myinput = input("내용을 입력해주세요: ")
파이썬에서 가장 기본적으로 사용하는 standard input 함수이다. 앞서 설명한 stdin 패키지를 사용한다. 즉, file descriptor 0번에 해당하는 standard input을 사용하는 stdin 객체를 사용하는 것이다.
백준과 같은 코딩 테스트 문제를 풀다보면 빠른 입력을 이용해야 문제를 풀 수 있는 경우가 종종 있다. 그런 종류의 문제의 경우 input() 함수 대신 stdin.readline()을 사용하여야 문제를 풀 수 있다. stdin 객체를 사용하는 것이 input() 함수를 사용하는 것보다 왜 속도가 더 빠를까? 가장 근본적인 정답은 앞서 설명했듯이 input() 함수가 stdin 객체의 기능에 자체적인 기능을 더한 함수이기 때문이다.
input() = stdin의 기능 + 자체적인 기능
input() 함수만의 자체적인 기능이라고 하면 대표적으로 인자로 받는 string을 출력하는 기능이다. 인자로 받는 string을 출력하는 작업이 굉장히 무거운 작업이기 때문에 이 기능을 집어넣은 input() 함수를 통해 입력을 받는 작업은 stdin을 이용하는 것보다 훨씬 무겁다.