FIFO가 파이프라는 이름을 들었습니다. 그리고 그들은 정확히 같은 의미론을 가지고 있습니다. 반면에 유닉스 도메인 소켓은 파이프와 매우 유사하다고 생각합니다. 그래서 그들이 모두 리눅스 커널에서 동일한 구현을 참조하는지 궁금합니다. 어떤 생각?
FIFO가 파이프라는 이름을 들었습니다. 그리고 그들은 정확히 같은 의미론을 가지고 있습니다. 반면에 유닉스 도메인 소켓은 파이프와 매우 유사하다고 생각합니다. 그래서 그들이 모두 리눅스 커널에서 동일한 구현을 참조하는지 궁금합니다. 어떤 생각?
답변:
UNIX 도메인 소켓과 FIFO는 구현의 일부를 공유 할 수 있지만 개념 상 매우 다릅니다. FIFO는 매우 낮은 수준에서 작동합니다. 한 프로세스는 파이프에 바이트를 쓰고 다른 프로세스는 파이프에서 읽습니다. UNIX 도메인 소켓은 TCP / IP 소켓과 동일한 동작을합니다.
소켓은 양방향이며 많은 프로세스에서 동시에 사용할 수 있습니다. 프로세스는 동일한 소켓에서 많은 연결을 허용하고 동시에 여러 클라이언트에 참석할 수 있습니다. 커널 은 매번 새로운 파일 디스크립터를 제공 connect(2)
하거나 accept(2)
소켓에서 호출됩니다. 패킷은 항상 올바른 프로세스로 진행됩니다.
FIFO에서는 불가능합니다. 양방향 통신을 위해서는 두 개의 FIFO가 필요하며 각 클라이언트마다 한 쌍의 FIFO가 필요합니다. 의사 소통하는 훨씬 더 원시적 인 방법이기 때문에 선택적인 방식으로 글을 쓰거나 읽는 방법은 없습니다.
익명 파이프와 FIFO는 매우 유사합니다. 차이점은 익명 파이프가 파일 시스템에 파일로 존재하지 않으므로 프로세스가 open(2)
불가능하다는 것입니다. 다른 방법으로 공유하는 프로세스에서 사용됩니다. 프로세스가 FIFO를 연 다음 예를 들어 a를 수행 fork(2)
하면 해당 자식은 파일 설명자와 그 중에서 파이프를 상속합니다.
UNIX 도메인 소켓, 익명 파이프 및 FIFO는 공유 메모리 세그먼트를 사용한다는 점에서 비슷합니다. 구현의 세부 사항은 시스템마다 다를 수 있지만 아이디어는 항상 동일합니다. 두 개의 개별 프로세스 메모리 매핑에 동일한 메모리 부분을 연결하여 데이터를 공유하도록하십시오
( 편집 : 그것을 구현하는 확실한 방법이지만 실제로 버퍼에서 커널 메모리를 사용하는 Linux에서 실제로 수행되는 방식이 아니라 아래 @ tjb63의 답변을 참조하십시오.
그런 다음 커널은 시스템 호출을 처리하고 메커니즘을 추상화합니다.
여기에 대한 좋은 토론이 있습니다 : http://www.slideshare.net/divyekapoor/linux-kernel-implementation-of-pipes-and-fifos
내가 볼 수있는 한 프리젠 테이션 슬라이드와 소스 @ http://lxr.free-electrons.com/source/fs/pipe.c-fifo 는 파이프 주위의 래퍼로 구현되며 파이프 자체는 pipefs 가상 파일 시스템을 통해 구현됩니다.
@lgeorget - 배관 파이프는 독자와 작가 사이의 버퍼에 대한 커널 메모리를 사용하도록 표시 - 그들은 같은 '공유 메모리'를 사용하지 않으며, 사용자와 커널 주소 공간 (예를 들어, 사이에 메모리를 복사 pipe_read
통화 pipe_iov_copy_to_user
, 어떤 통화 __copy_to_user_inatomic
(또는 copy_to_user
) . __copy_to_user_inatomic
통화 copy_user_generic
여러 ASM의 구현에있다.
"FIFO"와 " named pipe"는 동일하지만 쉘이 명령 행의 두 명령 사이에서 "pipe"(|)를 처리하는 방법과는 상당히 다릅니다.
명명 된 파이프 (FIFO)는 두 개의 프로그램이 공유하는 단일 "파일"입니다. 하나는 파일에 쓰고 다른 하나는 그 파일에서 읽습니다. 반면에 소켓은 두 "파일"사이의 "연결"입니다. 하나의 프로그램이 하나의 "파일"에 읽고 다른 프로그램은 다른 하나에 읽고 쓰는 다른 네트워크에 네트워크를 사용하고 다른 컴퓨터에 읽습니다. 소켓, 명명 된 파이프 (파일, 장치, 심볼릭 링크)는 모두 inode를 사용하며 모두 공통 기능 (읽기 및 쓰기)을 구현합니다.
저스틴은 그렇게 생각하지 않습니다. 내가 실수하지 않았고 아마도 FIFO가 디스크의 파일을 사용하고 Unix Domain 소켓이 커널 메모리를 사용한다고 생각합니다.
또한 Unix 도메인 소켓이 양방향이라고 언급 한 위의 포스터 외에도 SOCK_STREAM 소켓을 사용할 때만 해당됩니다. SOCK_DGRAM Unix 도메인 소켓은 실제로 단방향이며 connect ()를 호출 한 코드에서 bind ()를 호출 한 코드로만 send ()를 보낼 수 있습니다.
물론 connect ()라는 코드는 bind ()를 호출하여 자체 끝점을 만들어야하지만 질문과는 관련이 없습니다.
내 2 센트 ... FIFO와 UNIX 소켓은 양방향 (유사한)이지만 소켓에는 스타 토폴로지가 있지만 FIFO는 대기열이므로 서로를 대체 할 수는 없습니다. 그렇습니다. 구현은 내부적으로 코드를 공유 할 수 있습니다.
**
char * myfifo = "/tmp/myfifo";
mkfifo(myfifo, 0666);
fd = open(myfifo, O_RDWR); //so that you can read/write to it
...
write(fd, buff1, sizeof(buff1));
getchar();//wait till some one reds this and writes something else
int sz=read(fd, buff1, sizeof(buff1)); //read that something**