문제

소켓 하나가 있으면 어떻게됩니까? s, 현재 사용 가능한 데이터가 없으며 차단 소켓이며 recv 두 스레드에서 한 번에? 스레드 중 하나가 데이터를 얻을 수 있습니까? 둘 다 그것을 얻을까요? 두 번째로 전화 할 것입니다 recv 오류로 반환 하시겠습니까?

도움이 되었습니까?

해결책

하나의 스레드가 얻을 수 있으며 어느 것을 알 수있는 방법이 없습니다.

이것은 합리적인 디자인처럼 보이지 않습니다. 두 개의 스레드를 호출 해야하는 이유가 있습니까? recv() 같은 소켓에?

다른 팁

소켓 구현은 스레드 안전이어야하므로 정확히 하나의 스레드가 데이터를 사용할 수있게되면 데이터를 가져와야합니다. 다른 통화는 차단해야합니다.

나는 이것에 대한 참조를 찾을 수 없지만 여기에 내 이해가 있습니다.

공급 업체의 보증 스레드 안전성 여러 스레드가 각각 안전하게 사용할 수 있음을 의미 할 수 있습니다. 소유하다 소켓; 보장하지 않습니다 원자력 한 번의 통화에 걸쳐 여러 스레드간에 소켓 데이터를 특정 할당하지 않습니다.

TCP 데이터 스트리밍을 높은 속도로 수신하는 소켓에서 Thread a Call recv ()를 가정 해보십시오. recv ()가 원자 통화가되어야하는 경우, 스레드 A는 다른 모든 스레드가 실행되는 것을 막을 수 있습니다. 모든 데이터를 끌어 당기려면 (어쨌든 버퍼가 가득 찼을 때까지) 지속적으로 실행해야하기 때문입니다. 좋은. 따라서 recv ()가 상황 전환에 면역이된다고 가정하지 않습니다.

반대로, 스레드 a가 a 블로킹 TCP 소켓에서 recv ()로 호출하면 데이터가 느리게 나옵니다. 따라서 recv ()에 대한 호출은 errno가 eagain으로 설정된 상태에서 반환됩니다.

이들 중 어느 경우에서도 스레드 A가 여전히 데이터를 수신하는 동안 스레드 B가 동일한 소켓에서 recv ()을 호출한다고 가정합니다. 스레드 B가 데이터를 수신하기 시작할 수 있도록 스레드 A가 데이터를 건네주는 경우는 언제입니다. 나는 스레드 A가 소켓에서 작동의 중간에 있다는 것을 기억하려고 노력할 UNIX 구현을 모른다. 대신, 응용 프로그램 (스레드 A 및 B)에 달려있어 사용을 협상합니다.

일반적으로 스레드 중 하나만 단일 소켓에서 recv ()을 호출하도록 앱을 설계하는 것이 가장 좋습니다.

로부터 남자 페이지 recv

SOCK_STREAM 소켓의 recv ()는 제공된 버퍼의 크기가 보유 할 수있는만큼 사용 가능한 많은 정보를 반환합니다.

TCP가 질문에 지정되지 않았으므로 TCP를 사용하고 있다고 가정하자. 따라서 소켓에 대한 recv ()에서 스레드 A와 스레드 B가 차단되어 있다고 가정 해 봅시다. S가 수신 할 데이터가 있으면 스레드 중 하나를 차단 해제하고 A라고 말하고 데이터를 반환합니다. 반환 된 데이터는 우리가 염려하는 한 임의의 크기가 될 것입니다. 스레드 a는 수신 된 데이터를 검사하고 메시지가 응용 프로그램 수준 개념 인 완전한 "메시지"가 있는지 결정합니다.

스레드 a는 완전한 메시지가 없다고 결정하므로 다시 recv ()을 호출합니다. 그러나 그 동안 B는 이미 같은 소켓에서 차단되었고 스레드 A를 위해 의도 된 나머지 "메시지"를 받았습니다. 나는 여기에 느슨하게 의도 된 것을 사용하고 있습니다.

이제 스레드 A와 스레드 B에는 불완전한 메시지가 있으며 코드가 작성되는 방식에 따라 데이터를 유효하지 않은 것으로 버리거나 이상하고 미묘한 오류를 일으 킵니다.

나는 이것을 경험에서 알지 못했다고 말할 수 있으면 좋겠다.

따라서 recv () 자체는 기술적으로 스레드 안전이지만 TCP에 사용하는 경우 동시에 두 개의 스레드를 부르는 것은 나쁜 생각입니다.

내가 아는 한 UDP를 사용할 때는 완전히 안전합니다.

이게 도움이 되길 바란다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top