Pergunta

O que acontece se eu tiver um socket, s, não há dados actualmente disponíveis sobre ele, ele é um soquete de bloqueio, e eu chamo recv sobre ele a partir de dois segmentos de uma vez? Será um dos tópicos obter os dados? Será tanto obtê-lo? Será que a 2ª chamada para retorno recv com um erro?

Foi útil?

Solução

Um segmento vai buscá-la, e não há nenhuma maneira de saber qual.

Este não parece ser um projeto razoável. Existe uma razão pela qual você precisa de duas threads chamando recv() sobre o mesmo soquete?

Outras dicas

implementações de soquete deve ser thread-safe, então exatamente um segmento deve obter os dados quando ele estiver disponível. A outra chamada deve apenas bloquear.

Não consigo encontrar uma referência para isso, mas aqui está o meu entendimento:

garantia de um fornecedor de thread-segurança pode significar apenas que múltiplos threads cada um pode usar com segurança seus próprios soquetes; Ele não garante atomicity através de uma única chamada, e não promete qualquer atribuição específica de dados do soquete entre vários segmentos.

Suponha que o segmento A chamadas recv () em um soquete que está recebendo dados TCP em streaming a uma taxa elevada. Se recv () precisa ser uma chamada atômica, enrosque A poderia bloquear todos os outros tópicos de executar, porque ele precisa ser executado continuamente para puxar todos os dados (até o buffer está cheio, de qualquer maneira.) Isso não seria Boa. Por isso, eu não diria que recv () é imune a troca de contexto.

Por outro lado, linha Suponha que um faz uma bloqueando chamada para recv () em um soquete TCP, e os dados estão vindo lentamente. Daí a chamada para recv () retorna com errno conjunto para EAGAIN.

Em qualquer destes casos, suponha segmento B chama recv () no mesmo soquete enquanto thread A ainda está recebendo dados. Quando o fio de uma paragem de obtenção de dados entregues a ele para que segmento B pode começar a receber dados? Eu não sei de uma implementação de Unix que vai tentar lembrar que thread A estava no meio de uma operação no soquete; em vez disso, cabe a aplicação (tópicos A e B) para negociar o uso do mesmo.

Geralmente, é melhor para projetar o aplicativo para que apenas um dos tópicos chamará recv () em uma única tomada.

A partir da homem página em recv

A recv () em um SOCK_STREAM tomada retorna como muita informação disponível medida que o tamanho do tampão fornecido lata espera.

Vamos supor que você está usando TCP, uma vez que não foi especificado na pergunta. Então, suponha que você tenha thread A e linha B ambos bloqueio em recv () para o soquete s. Uma vez que s tem alguns dados a serem recebidos ele vai desbloquear um dos tópicos, digamos A, e retornar os dados. Os dados retornados será de alguma tamanho aleatória, tanto quanto estamos preocupados. Tópico A inspeciona os dados recebidos e decide se ele tem uma "mensagem" completa, onde uma mensagem é um conceito de nível de aplicativo.

Thread A decide que não tem uma mensagem completa, por isso chama recv () novamente. Mas, entretanto B já estava bloqueando no mesmo soquete, e recebeu o resto da "mensagem" que foi destinado para a linha A. Eu estou usando destina vagamente aqui.

Agora, tanto segmento A e linha B tem uma mensagem incompleta, e, dependendo de como o código é escrito, jogue os dados afastado como inválido, ou causa erros estranhos e sutis.

Eu gostaria de poder dizer que eu não sei disso por experiência.

Assim, enquanto recv () em si é tecnicamente o segmento de seguros, é uma má idéia ter dois threads chamando-o simultaneamente se você estiver usando-o para TCP.

Tanto quanto eu sei que é completamente seguro quando você estiver usando UDP.

Espero que isso ajude.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top