Les appels parallèles à envoyer / recv sur le même socket sont-ils valides?

  1. Peut-on appeler send depuis un thread et recv depuis un autre sur le même socket?
  2. Peut-on appeler plusieurs envois en parallèle à partir de différents threads sur le même socket?

Je sais qu’une bonne conception devrait éviter cela, mais je ne vois pas comment ces API système se comporteront. Je suis incapable de trouver une bonne documentation pour le même.

Tout pointeur dans la direction sera utile.

POSIX définit send / recv comme des opérations atomiques, donc en supposant que vous parliez de POSIX send / recv, alors oui, vous pouvez les appeler simultanément à partir de plusieurs threads et tout fonctionnera.

Cela ne signifie pas nécessairement qu’ils seront exécutés en parallèle – dans le cas d’envois multiples, le second sera probablement bloqué jusqu’à ce que le premier soit terminé. Vous ne le remarquerez probablement pas beaucoup, car un envoi se termine une fois que ses données sont entrées dans le tampon de socket.

Si vous utilisez les sockets SOCK_STREAM, essayer de faire des choses parallèlement est moins susceptible d’être utile car send / recv peut envoyer ou recevoir seulement une partie d’un message, ce qui signifie que les choses pourraient être fractionnées.

Le blocage de send / recv sur les sockets SOCK_STREAM ne bloque que lorsqu’ils envoient ou recv au moins 1 octet, donc la différence entre le blocage et le non-blocage n’est pas utile.

Le descripteur de socket appartient au processus, pas à un thread particulier. Par conséquent, il est possible d’envoyer / recevoir vers / depuis le même socket dans différents threads, le système d’exploitation va gérer la synchronisation.

Cependant, si l’ordre d’envoi / de réception est sémantiquement significatif, vous devez vous-même (respectivement votre code) assurer un séquençage correct entre les opérations dans les différents threads – comme c’est toujours le cas avec les threads.

Je ne vois pas comment recevoir en parallèle pourrait accomplir quelque chose. Si vous avez un message de 3 octets, 1 thread pourrait obtenir le premier 2 octets et un autre le dernier octet, mais vous n’auriez aucun moyen de savoir lequel. À moins que vos messages ne soient qu’un octet de long, il est impossible de faire en sorte que quelque chose fonctionne avec plusieurs threads.

Plusieurs envois peuvent fonctionner si vous avez envoyé le message entier en un seul appel, mais je ne suis pas sûr. Il est possible que l’on en écrase une autre. Il n’y aurait certainement aucun avantage de performance à le faire.

Si plusieurs threads doivent envoyer, vous devez implémenter une queue de messages synchronisée. Avoir un thread qui effectue l’envoi qui lit les messages de la queue et fait en sorte que les autres threads mettent en queue des messages entiers. La même chose fonctionnerait pour recevoir, mais le thread de réception devrait connaître le format des messages pour pouvoir les désérialiser correctement.