Questo è più di un'osservazione e anche un suggerimento per che cosa è il modo migliore per gestire questo scenario.sendto() non bloccano i dgram per ENOBUFS su OSX
Ho due thread uno solo pompa i dati e un altro riceve i dati e fa molto lavoro prima di inviarlo un altro socket. Entrambi i thread sono collegati tramite un socket Domain. Il protocollo usato qui è UDP. Non volevo usare TCP perché è basato sul flusso, il che significa che se c'è poco spazio nella coda i miei dati vengono divisi e inviati. Questo è un male perché Iam invia dati che non dovrebbero essere divisi. Quindi ho usato DGRAM. È interessante notare che quando il thread send sovrascrive il thread recv pompando così tanti dati, a un certo punto il buffer del socket Domain viene riempito e sendto() restituisce ENOBUFS. Ero dell'opinione che se ciò dovesse accadere, sendto() bloccherebbe fino a quando il buffer non sarà disponibile. Questo sarebbe il mio comportamento desiderato. Tuttavia questo non sembra essere il caso. Risolvo questo problema in un modo piuttosto strano.
metodo del rendimento CPU Se ottengo ENOBUFS, faccio uno sched_yield(); poiché non c'è pthread_yield() in OSX. Dopo di ciò, provo a inviare nuovamente il nuovo messaggio. Se fallisce, continuo a fare lo stesso fino a quando non viene preso. Questo è male perché Iam spreca cicli di CPU solo facendo qualcosa di inutile. Mi piacerebbe se sendto() bloccato.
Metodo sleep Ho provato a risolvere lo stesso problema usando sleep (1) invece di sched_yield(), ma questo di non utilizzare sleep() avrebbe messo il mio processo in sleep invece di solo quel thread di invio.
Entrambi non sembra funzionare per me e Iam a corto di opzioni. Qualcuno può suggerire qual è il modo migliore per gestire questo problema? C'è qualche trucco intelligente di cui non sono consapevole che possa ridurre inutili cicli di CPU? btw, ciò che la pagina man dice di SentTo() è sbagliato, sulla base di questa discussione http://lists.freebsd.org/pipermail/freebsd-hackers/2004-January/005385.html
Il codice Upd nel kernel:
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;
}
Come si generano i fili? In realtà, [sleep (3)] (https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man3/sleep.3.html) dovrebbe funzionare per i thread POSIX. – artistoex