2009-12-30 2 views
96
  1. 하나의 스레드에서 send를 호출하고 동일한 소켓에서 다른 스레드로부터 recv를 호출 할 수 있습니까?
  2. 같은 소켓에있는 여러 스레드에서 여러 개의 송신을 병렬로 호출 할 수 있습니까?

나는 좋은 디자인이 이것을 피해야한다는 것을 알고 있지만,이 시스템 API가 어떻게 동작 할 지 명확하지 않습니다. 나는 같은 문서를 찾을 수 없다.동일한 소켓에서 send/recv에 대한 병렬 호출이 유효합니까?

방향에있는 포인터가 도움이 될 것입니다.

+0

왜 그렇게하는 것이 나쁜 습관이라고 주장합니까? 당신이 다른 스레드에서 듣고받을 수 있기 때문에 괜찮아 보입니다. – TheMathNoob

답변

72

POSIX는 send/recv를 원자 적 연산으로 정의하므로 POSIX send/recv에 대해 이야기하고 있다고 가정하면 여러 스레드에서 동시에 호출 할 수 있습니다.

이것은 반드시 병렬로 실행된다는 의미는 아닙니다. 다중 전송의 경우 두 번째는 첫 번째 완료까지 차단 될 가능성이 큽니다. 소켓 버퍼에 데이터를 저장 한 후에는 보내기가 완료 될 때마다이 사실을 알 수 없을 것입니다.

SOCK_STREAM 소켓을 사용하는 경우 send/recv가 메시지의 일부만 보내거나받을 수 있으므로 병행 작업을 시도하면 유용하지 않을 수 있습니다.

SOCK_STREAM 소켓의 send/recv 차단은 최소 1 바이트를 보내거나 recv 할 때까지만 차단하므로 블로킹과 비 블로킹의 차이점은 유용하지 않습니다.

+0

send/recv 차단은 어떻게하나요? 원자가? – Jay

+0

이 기사 (http://www.almaden.ibm.com/cs/people/marksmith/sendmsg.html)는 SOCK_STREAM에 대한 의견을 확인하는 것으로 보이지만 SOCK_DGRAM에 대해서는 명확하지 않으므로 정확히 어디에서 정보를 얻었습니까? –

+1

@ Joao : SOCK_DGRAM 소켓은 "메시지 경계 보존"으로 문서화되어 있습니다. 이는 명확하지 않습니다. 리눅스 커널 소스를 살펴보면 각 send와 recv가 하나의 패킷을 원자 적으로 처리한다는 것을 적어도 알 수 있습니다 (적어도 udp의 경우). –

2

평행선을받는 것이 어떻게 달성 할 수 있는지는 알 수 없습니다. 3 바이트 메시지가있는 경우 1 스레드는 첫 번째 2 바이트를 가져올 수 있고 다른 바이트는 마지막 바이트를 가져올 수 있지만 어느 것이 어떤 것인지 알 수있는 방법이 없습니다. 메시지가 단지 1 바이트 길이가 아니라면, 여러 스레드가 수신하는 작업을 안정적으로 수행 할 수있는 방법은 없습니다.

한 번에 전체 메시지를 보냈지 만 복수 발신 일 수도 있고 일 수도 있습니다. 확실하지 않습니다. 다른 사람이 다른 사람을 겹쳐 쓸 수도 있습니다. 그렇게 할 때 어떤 성능상의 이점도 없을 것입니다.

여러 스레드가 전송해야하는 경우 동기화 된 메시지 큐를 구현해야합니다. 대기열에서 메시지를 읽고 다른 스레드가 전체 메시지를 대기열에 포함시키는 실제 전송을 수행하는 하나의 스레드를 만듭니다. 수신 할 때도 똑같이 작동하지만 수신 스레드는 메시지의 형식을 알고 있어야 제대로 메시지를 비 직렬화 할 수 있습니다.

+6

SOCK_DGRAM 소켓을 사용하는 경우, 각 recv는 단일 데이터 그램을 얻습니다. 그것 recvs 사이에 결코 분할되지 않습니다 –

+2

@ 노아, 나는 병렬 recvs 아무것도 달성 할 수 없다는 데 동의합니다. 그래서 내가 묻지 않았다. 내 질문은/recv 병렬로 보낸 다음 여러 병렬로 보냅니다. 귀하의 대답은 병렬 송신에 대한 통찰력을 제공합니다. 같은 주셔서 감사합니다. – Jay

+1

@Chris 좋은 지적. 나는 TCP를 추측하고 있었다. @ 제이 "평소에 보내기/받기"를 할 수있는 것처럼 들리겠습니까? – noah

11

소켓 설명자는 특정 스레드가 아닌 프로세스에 속합니다. 따라서 서로 다른 스레드에서 같은 소켓으로 보내거나받을 수 있습니다. OS가 동기화를 처리합니다.

그러나 보내기/받기의 순서가 의미 상으로 중요하면 스레드 (thread)의 경우와 같이 항상 서로 다른 스레드의 작업간에 올바른 순서를 지정해야합니다.

관련 문제