Unix / Linux는 파이프, 소켓, 공유 메모리, dbus, 메시지 큐 등 많은 IPC를 제공합니다.
각각에 가장 적합한 응용 프로그램은 무엇이며 어떻게 수행합니까?
답변:
다음은 빅 7입니다.
FIFO 또는 명명 된 파이프
무관 한 두 개의 프로세스는 일반 파이프와 달리 FIFO를 사용할 수 있습니다. 에게 전화하십시오 mkfifo(3)
. 단방향.
양방향. 네트워크 통신을 의미하지만 로컬에서도 사용할 수 있습니다. 다른 프로토콜에 사용할 수 있습니다. TCP에는 메시지 경계가 없습니다. 에게 전화하십시오 socket(2)
.
OS는 개별 메시지를 유지합니다. sys / msg.h를 참조하십시오 .
Signal은 정수를 다른 프로세스로 보냅니다. 다중 스레드와 잘 맞지 않습니다. 에게 전화하십시오 kill(2)
.
욕실을 기다리는 사람들의 대기열과 유사한 다중 프로세스 또는 스레드에 대한 동기화 메커니즘입니다. sys / sem.h를 참조하십시오 .
자신의 동시성 제어를 수행하십시오. 에게 전화하십시오 shmget(2)
.
한 방법을 다른 방법보다 선택할 때 결정적인 요소 중 하나는 메시지 경계 문제입니다. "메시지"는 서로 분리되어있을 것으로 예상 할 수 있지만 TCP 또는 파이프와 같은 바이트 스트림에는 해당되지 않습니다.
에코 클라이언트와 서버 쌍을 고려하십시오. 클라이언트는 문자열을 보내고 서버는 문자열을 받아 바로 다시 보냅니다. 클라이언트가 "Hello", "Hello"및 "How about an answer?"를 전송한다고 가정합니다.
바이트 스트림 프로토콜을 사용하면 서버는 "Hell", "oHelloHow"및 "about an answer?"로 수신 할 수 있습니다. 또는 더 현실적으로 "HelloHelloHow에 대한 답변?" 서버는 메시지 경계가 어디에 있는지 전혀 알지 못합니다.
노년 트릭에 메시지 길이를 제한하는 것입니다 CHAR_MAX
나 UINT_MAX
하고 먼저 메시지 길이를 보내 동의 char
나 uint
. 따라서 수신 측에 있다면 먼저 메시지 길이를 읽어야합니다. 이것은 또한 한 번에 하나의 스레드 만 메시지 읽기를 수행해야 함을 의미합니다.
UDP 또는 메시지 큐와 같은 개별 프로토콜을 사용하면이 문제에 대해 걱정할 필요가 없지만 프로그래밍 방식으로 바이트 스트림은 파일 및 stdin / out처럼 동작하기 때문에 처리하기가 더 쉽습니다.
공유 메모리는 그 위에 고유 한 통신 체계를 구축하기 때문에 가장 효율적일 수 있지만 많은주의와 동기화가 필요합니다. 공유 메모리를 다른 시스템에 배포 할 수있는 솔루션도 있습니다.
소켓은 요즘 가장 이식성이 좋지만 파이프보다 더 많은 오버 헤드가 필요합니다. 소켓을 로컬로 또는 네트워크를 통해 투명하게 사용하는 기능은 큰 보너스입니다.
메시지 큐 및 신호는 하드 실시간 애플리케이션에 적합 할 수 있지만 유연하지는 않습니다.
이러한 방법은 자연스럽게 프로세스 간의 통신을 위해 만들어졌으며 프로세스 내에서 여러 스레드를 사용하면 특히 신호와 관련하여 상황이 복잡해질 수 있습니다.
다음은 간단한 벤치 마크가있는 웹 페이지입니다. https://sites.google.com/site/rikkus/sysv-ipc-vs-unix-pipes-vs-unix-sockets
내가 말할 수있는 한, 각각의 장점은 다음과 같습니다.
많은 라이브러리가 한 가지 유형을 다른 유형 위에 구현한다는 점은 주목할 가치가 있습니다.
공유 메모리는 끔찍한 sysv 공유 메모리 함수를 사용할 필요가 없습니다. mmap ()을 사용하는 것이 훨씬 더 우아합니다 (이름을 지정하려면 tmpfs / dev / shm에있는 파일을 mmap, 원하는 경우 mmap / dev / zero). 익명으로 상속하기 위해 실행되지 않은 프로세스를 분기합니다). 그렇긴하지만, 문제를 피하기 위해 동기화가 필요한 프로세스를 남겨 둡니다. 일반적으로 다른 IPC 메커니즘을 사용하여 공유 메모리 영역에 대한 액세스 동기화를 수행합니다.