- 하나의 스레드에서 send를 호출하고 동일한 소켓의 다른 스레드에서 recv를 호출 할 수 있습니까?
- 동일한 소켓의 다른 스레드에서 여러 전송을 병렬로 호출 할 수 있습니까?
좋은 디자인은 이것을 피해야한다는 것을 알고 있지만 이러한 시스템 API의 작동 방식은 확실하지 않습니다. 나는 또한 좋은 문서를 찾을 수 없다.
방향에 대한 포인터가 도움이 될 것입니다.
답변
POSIX는 send / recv를 원자 연산으로 정의하므로 POSIX send / recv에 대해 이야기하고 있다고 가정하면 여러 스레드에서 동시에 호출 할 수 있으며 작동합니다.
이것은 반드시 병렬로 실행될 것이라는 것을 의미하지는 않습니다. 여러 전송의 경우 두 번째는 첫 번째가 완료 될 때까지 차단 될 것입니다. 송신이 일단 데이터를 소켓 버퍼에 넣은 후에는 완료되므로이 점을 많이 알지 못할 것입니다.
SOCK_STREAM 소켓을 사용하는 경우 send / recv가 메시지의 일부만 보내거나받을 수 있으므로 병렬 작업을 시도하는 것이 유용하지 않을 수 있습니다.
SOCK_STREAM 소켓에서 send / recv를 차단하면 최소 1 바이트를 보내거나받을 때까지만 차단되므로 차단과 비 차단의 차이는 유용하지 않습니다.
답변
소켓 디스크립터는 특정 스레드가 아닌 프로세스에 속합니다. 따라서 다른 스레드에서 동일한 소켓으로 송수신 할 수 있으며 OS는 동기화를 처리합니다.
그러나 송신 / 수신 순서가 의미 적으로 중요한 경우, 항상 스레드와 마찬가지로 다른 스레드의 작업간에 적절한 순서를 지정해야합니다.
답변
병렬로받는 것이 어떻게 성취 할 수 있는지 보지 못합니다. 3 바이트 메시지가있는 경우 1 스레드는 첫 번째 2 바이트와 다른 바이트를 얻을 수 있지만 어느 것이 어느 것인지 알 수는 없습니다. 메시지 길이가 1 바이트가 아닌 이상 여러 스레드 수신에서 안정적으로 작업 할 수있는 방법이 없습니다.
한 번의 호출로 전체 메시지를 보낸 경우 여러 번의 전송 이 작동 할 수 있지만 확실하지 않습니다. 하나는 다른 것을 덮어 쓸 수 있습니다. 그렇게하면 성능상의 이점이 없을 것입니다.
여러 스레드를 보내야하는 경우 동기화 된 메시지 큐를 구현해야합니다. 큐에서 메시지를 읽는 실제 전송을 수행하는 스레드 하나와 전체 메시지를 큐에 넣는 스레드가 있습니다. 수신에서도 마찬가지이지만 수신 스레드는 메시지의 형식을 알아야 직렬화를 해제 할 수 있습니다.