Il s'agit davantage d'une observation et d'une suggestion quant à la meilleure façon de gérer ce scénario.sendto() Les dgrams ne bloquent pas pour ENOBUFS sous OSX
J'ai deux threads, l'un pompe les données et l'autre les données et fait beaucoup de travail avant de lui envoyer une autre socket. Les deux threads sont connectés via une socket de domaine. Le protocole utilisé ici est UDP. Je ne voulais pas utiliser TCP car il est basé sur les flux, ce qui signifie que s'il y a peu d'espace dans la file d'attente, mes données sont partagées et envoyées. C'est mauvais car j'envoie des données qui ne devraient pas être divisées. D'où j'ai utilisé DGRAM. Il est intéressant de noter que lorsque le thread d'envoi submerge le thread de recv en pompant tant de données, le buffer du socket de domaine est à un certain point rempli et sendto() renvoie ENOBUFS. J'étais d'avis que si cela arrivait, sendto() bloquerait jusqu'à ce que le tampon soit disponible. Ce serait mon comportement désiré. Cependant, cela ne semble pas être le cas. Je résous ce problème d'une manière plutôt étrange.
CPU Méthode du rendement Si je ENOBUFS, je fais un sched_yield(); comme il n'y a pas pthread_yield() dans OSX. Après cela, j'essaie de renvoyer à nouveau. Si cela échoue, je continue à faire la même chose jusqu'à ce qu'elle soit prise. C'est mauvais comme Iam gaspiller des cycles de cpu faisant juste quelque chose inutile. J'aimerais si sendto() bloqué. J'ai essayé de résoudre le même problème en utilisant sleep (1) au lieu de sched_yield() mais cela ne sert à rien car sleep() mettrait mon processus en veille au lieu de simplement envoyer ce thread.
Les deux ne semblent pas fonctionner pour moi et je suis à court d'options. Quelqu'un peut-il suggérer quelle est la meilleure façon de gérer ce problème? Y a-t-il des astuces intelligentes que je ne connais pas qui peuvent réduire les cycles inutiles de cpu? BTW, ce que la page de l'homme dit à propos SentTo() ne va pas, sur la base de cette discussion http://lists.freebsd.org/pipermail/freebsd-hackers/2004-January/005385.html
Le code Upd dans le noyau:
The udp_output function in /sys/netinet/udp_usrreq.c, seems clear:
/*
* Calculate data length and get a mbuf
* for UDP and IP headers.
*/
M_PREPEND(m, sizeof(struct udpiphdr), M_DONTWAIT);
if (m == 0) {
error = ENOBUFS;
if (addr)
splx(s);
goto release;
}
Comment générer les threads? En fait, [sleep (3)] (https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man3/sleep.3.html) devrait fonctionner pour les threads POSIX. – artistoex