Posix

Haiseong Jeong·2022년 11월 3일
2
post-thumbnail

Posix

POSIX(Portable Operating System Interface)는 이식가능 운영체제 인터페이스의 약자다. 한 운영체제에서 개발한 프로그램을 다른 운영체제에서도 쉽게 돌아가도록 하고 서로 운영체제가 달라도 같은 Command line으로 명령을 내릴 수 있다. Posix는 Unix에 기반하여 만들어 졌다. Posix 인증을 받은 OS는 대표적으로 MAC OS가 있다. Linux도 인증을 받지는 못했지만 대부분의 기능이 POSIX 표준을 지키고 있다. Windows는 Posix를 따르지 않는다. Posix 표준을 지키는 OS환경을 Unix-like environments 라고 한다. 따라서 MAC OS와 Linux는 Unix-like 하다고 말할 수 있다.

Standard Stream

표준 스트림은 Posix를 따르는 OS에 컴퓨터에 연결된 입출력 통로를 가리킨다. 표준스트림은 표준 입력, 표준 출력, 표준 오류가 있다.

표준입력(STDIN): 표준 입력 장치의 ID 는 숫자로는 0 이며 일반적으로는 키보드다.
표준출력(STDOUT): 출력을 위한 스트림으로 표준 출력 장치의 ID 는 1이며 일반적으로는 현재 쉘을 실행한 콘솔이다.
표준에러(STDERR): 에러를 위한 스트림으로 표준 에러 장치의 ID 는 2이며 일반적으로는 표준 출력과 동일하다.

pipes

파이프는 어떤 프로그램의 출력 결과를 다음 단계의 입력값으로 이어지는 형태로 연결된 구조를 뜻한다.

man cat | grep POSIX

위의 명령어는 프로세스 하나로 동작하는 것처럼 보이지만 사실 두개의 프로세스로 돌아간다. man cat, grep POSIX 이렇게 각각의 프로세스로 작동한다. 위 두개의 프로세스는 pipe(|)로 정보를 주고 받는다. 파이프를 기준으로 왼쪽 프로세스 man cat의 결과 값이 오른쪽 프로세스 grep POSIX의 input 값으로 들어간다. pipe는 총 2개의 파일을 생성한다. 하나는 왼쪽 프로세스가 자신의 결과값을 write하는 파일, 다른 하나는 오른쪽에서 read하는 파일이다.

pipe를 만들면 부모 프로세스는 파이프의 read_file과 write_file을 file descriptor에 등록한다. 부모 프로세스를 fork하면 자식이 부모의 file descriptor를 상속받는다. 파이프를 만들고 fork로 프로세스를 복사했다면 다음과 같은 모습이다.

mangrep중 무엇을 부모로 하고 무엇을 자식으로 정할까? 부모 프로세스와 자식 프로세스 중 무엇이 먼저 실행될지는 모른다. 우선 우리가 아는 것은 man cat은 write를 해야하고 grep POSIX는 read를 해야한다.

잠시 이야기를 돌려 read() 함수를 알아보자. read()는 EOF까지 파일을 읽는다. EOF는 파일의 끝을 의미한다. EOF를 만족할 중요한 조건이 하나 있는데, 그건 바로 모든 writer가 close되어야 한다는 것이다. 자식이 read기능을 실행한다면 자식의 write_file descriptor는 열려있으면 안된다. 따라서 man cat을 부모로 하면 자식인 grep POSIX의 write_file을 close() 해줘야 한다. 그래야 EOF를 만족시킬 수 있다.

또한 자식의 read_file도 닫는 것이 권장된다. 왜냐하면 프로세스가 불필요한 여러개 파일에 접근하고 있는 것은 좋지 않기 때문이다. file descriptor 갯수에도 제한이 있기에 필요없는 파일은 닫는 것이 좋다. 또한 쓰는 입장에서 여러명이 파일을 읽고 있으면 진짜 reader가 누군지 판단하기 힘들다.

profile
나는 개발자다. 5000만큼 코딩한다.

0개의 댓글