Pipe(이름 없는 파이프)
파이프라는 것은 같은 컴퓨터 안에서 돌고 있는 프로세스들 사이에 데이터를 주고받기 위해서 간단하게 사용할 수 있는 IPC 메커니즘이다.
Pipe의 특징
- 파이프는 이름이 없다. ls를 해도 아무것도 안 뜸 (네임프 파이프는 ls를 하면 파일이 있다.)
- 파이프는 일시적인 객체이다(temporary). 파이프를 사용하는 프로세스가 모두 종료를 하게 되면 사용했던 파이프 객체도 자동으로 소멸이 된다. (네임드 파이프는 프로세스가 모두 종료가 되더라도 삭제가 되는 것이 아니라 계속 남아있음) 파이프의 파일 디스크립터를 사용하는 프로세스가 없다면 파이프는 자동으로 삭제된다.)
- 두 개의 파일 디스크립터를 알고 있어야만 파이프를 access할 수 있다.(아무 프로세스나 파이프를 사용할수있는것은 아님, 파이프의 특성상 부모자식관게의 프로세스들이 사용할 수 있다. 부모자식관계가 아니라면 사용할 수 없다. 왜냐하면 이름도 없고 전혀상관없는 프로세스가 파일의 디스크립터를 알아낼수있는 방법이 없기떄문이다. fork()를 해서 프로세스가 자식을 만들고 자식은 부모의 파일디스크립터를 그대로 상속받는다. 부모가 pipe함수를 써서 두개의 파일디스크럽터가 오픈된다, 디스크립터 테이블 안에도 두개의 엔트리가 추가가 된다. 그다음에 부모프로세스가 fork를 하게되면 두개의 파일 디스크립터 정보가 자식프로세스에게 파일 디스크립터 테이블 엔트리가 그대로 상속이 된다. 그래서 자식프로세스도 부모가 오픈한 파이프의 파일 디스크립터 정보를 상속받게 된다. 이러한 이유 때문에 파이프를 엑세스할 수 있음)
- 두개의 파일 디스크립터 fd [0], fd [1]을 읽기 전용, 쓰기 전용으로 사용을 해야 한다. 혹시나 바꿔서 사용을 하면 오류가 발생할 것이다. POSIX에서는 잘못 사용했을 경우에 대한 것을 규정하지 않았기 때문에 무슨 일이 발생할지 모른다.
- 파이프를 통해서 read를 할 경우에 파이프의 상태에 따라서 달라진다(3가지 경우). fd [0]을 통해서 read함수를 호출을 하면 파이프로부터 데이터를 읽겠다는 것인데 이랬을 때 read함수가 즉각적으로 리턴을 하는 경우는 파이프가 비어있지 않을 경우(누군가가 파이프에 데이터를 써둔 것)이다. read함수는 파이프에 있는 데이터를 읽어서 바로 실제 읽은 바이트의 수를 리턴을 해준다(1번째). 그럼 만약 파이프가 비어있는 상태로 read함수를 호출할 경우에 어떻게 될까? 파이프가 비어있는 경우는 두 가지가 있다 먼저 파이프가 비어있지만 후에 프로세스가 파이프에 데이터를 써주는 경우이다. 혹은 아예 쓸 데이터가 없어서 앞으로도 데이터가 쓰일 일이 없을떄이다. 이 두가지 경우에 따라서 read함수가 다르게 작동한다. 파이프가 비어있고 어떤 프로세스가 파이프의 쓰기전용으로 오픈을 해놨다면(즉, 어떤 프로세스의 파일디스크립터 테이블안에 쓰기용 디시크립터를 가지고 있는 프로세스가 있으면(fd[1]을 의미) OS는 이 프로세스가 언제든지 write함수를 써가지고 파이프에 데이터를 쓸수 있겠구나 라고 판단을 한다. 그러면 read함수는 바로 리턴이 되는것이 아니고 block이 된다.(2번째) 마지막으로 read함수를 호출했을때 파이프가 비어있는데 이 파이프에 쓰기용으로 오픈한 프로세스가 아예없는 경우에는 OS는 기다려봤자 데이터가 쓰여질 일이 없다고 판단한다. 그래서 이러한 경우에는 read함수는 바로 0을 리턴을 한다.(read함수에서 0을 리턴한다는 얘기는 end of file을 의미) 파이프에서 파일의 끝을 의미한다는 것은 이 파이프에 쓸 프로세스가 지금도 없고 앞으로도 없다는 것을 의미한다.
- 기본적으로 파이프는 blocking I/O를 사용한다. 읽을 게 없으면 읽을거리가 있을 때까지 blocking이 된다. 있으면 그냥 읽음.
그렇다면 부모가 파이프에 hello를 쓰기 전에 자식프로세스가 먼저 read 하면 어떻게 될까?
자식프로세스가 비어있는 파이프에 대해서 read를 하게 되면 read함수는 block이 될 것이다. 그래서 부모가 hello를 써줄때까지 기다릴 것이다. 왜냐하면 파이프에 write용으로 오픈한 프로세스가 있기 때문에(부모자식 모두 fd[1] 보유중) 비어있는 파이프에대해서 read를 하게되면 block이 될것이다. 그렇기 때문에 누가먼저 실행이 되는지에 따라서 걱정할 필요가 없다.
FIFO(이름이 있는 파이프)
이름 없는 파이프는 temporary 하기 때문에 모든 프로세스들이 종료를 하게 되면 사용했던 파이프도 OS에 의해서 같이 삭제된다는 특징이 있었다.
그런데 일반 파일처럼 사용할 수 있는 파이프도 제공이 되었는데 이것을 FIFO or named pipe라고 한다.
FIFO는 일반파일을 만들 때 사용했던 것처럼 권한정보(rwx권한)를 지정을 해야 한다. FIFO는 이름 또한 지정해야 한다. 이름이 있기 때문에 permanent 하다. 그래서 ls를 하면 보임. 그렇기 때문에 FIFO의 이름을 알고 권한이 있다면 아무 프로세스와 통신이 가능하다.(pipe보다 사용범위가 넓음)
'Computer Science > 시스템 프로그래밍' 카테고리의 다른 글
[시스템 프로그래밍] Chapter 9 (0) | 2024.06.08 |
---|---|
[시스템 프로그래밍] Chapter 8 (0) | 2024.05.09 |
[시스템 프로그래밍] Chapter 5 (0) | 2024.05.08 |
[시스템 프로그래밍] Chapter 4 (0) | 2024.04.12 |
[시스템 프로그래밍] Chapter 3 (0) | 2024.04.10 |