Castecny zapis do socketu

Jan Kasprzak kas na fi.muni.cz
Čtvrtek Květen 1 23:06:45 CEST 2008


	Dobry vecer,

mam paralelni aplikaci ve stylu producenti-konzumenti: mam N producentu
a N konzumentu, navzajem kompletne spojenych pomoci socketu (pres TCP).
Producenti generuji nejaka data a zasilaji je jednotlivym konzumentum.
Producenti pracuji tak, ze maji pro kazdeho konzumenta datovou strukturu,
na zaklade ktere generuji data pro konkretniho konzumenta jen v pripade,
ze je prislusny socket pripraveny pro zapis (pouzivam knihovnu libev).

	Muj problem je, ze ackoli delam poll() a on mi rekne
ze socket je pripraveny k zapisu, tak nasledujici write() se zablokuje
a ceka - strace konci napriklad takto (omlouvam se za dlouhe radky):

poll([{fd=3, events=POLLIN}, {fd=0, events=POLLIN}, {fd=588, events=POLLOUT}, {fd=518, events=POLLOUT}, {fd=520, events=POLLOUT}, {fd=522, events=POLLOUT, revents=POLLOUT}, {fd=604, events=POLLOUT, revents=POLLOUT}, {fd=526, events=POLLOUT}, {fd=528, events=POLLOUT, revents=POLLOUT}, {fd=530, events=POLLOUT}, {fd=532, events=POLLOUT}, {fd=534, events=POLLOUT, revents=POLLOUT}, {fd=536, events=POLLOUT}, {fd=538, events=POLLOUT, revents=POLLOUT}, {fd=540, events=POLLOUT, revents=POLLOUT}, {fd=542, events=POLLOUT, revents=POLLOUT}, {fd=544, events=POLLOUT, revents=POLLOUT}, {fd=546, events=POLLOUT, revents=POLLOUT}, {fd=548, events=POLLOUT}, {fd=550, events=POLLOUT}, {fd=552, events=POLLOUT}, {fd=554, events=POLLOUT}, {fd=556, events=POLLOUT}, {fd=558, events=POLLOUT, revents=POLLOUT}, {fd=560, events=POLLOUT, revents=POLLOUT}, {fd=562, events=POLLOUT}, {fd=564, events=POLLOUT}, {fd=566, events=POLLOUT, revents=POLLOUT}, {fd=568, events=POLLOUT, revents=POLLOUT}, {fd=570, events=POLLOUT}, {fd=572, events=POLLOUT, revents=POLLOUT}, {fd=574, events=POLLOUT}, {fd=576, events=POLLOUT}, {fd=578, events=POLLOUT}, {fd=580, events=POLLOUT}, {fd=582, events=POLLOUT}, {fd=584, events=POLLOUT}, {fd=586, events=POLLOUT}, {fd=590, events=POLLOUT}, {fd=592, events=POLLOUT}, {fd=594, events=POLLOUT, revents=POLLOUT}, {fd=596, events=POLLOUT, revents=POLLOUT}, {fd=598, events=POLLOUT}, {fd=600, events=POLLOUT, revents=POLLOUT}, {fd=602, events=POLLOUT, revents=POLLOUT}], 45, 59743) = 18
write(602, ..., 16384) = 16384
write(600, ..., 16384
	(a nic, tady se to zasekne, klidne i na nekolik minut)

pritom jak je videt, i deskriptor 600 byl hlaseny jako pripraveny pro zapis.
Moje aplikace je korektne pripravena i na castecny write(), cili bych
cekal, ze kdyz nahodou jadro nepojme celych 16 KB dat do svych bufferu,
ze zapise aspon neco a vrati mi mene zapsanych dat.

	Protoze knihovna libev umi pouzit i jine backendy nez poll(),
zkousel jsem i tyto: epoll() se chova stejne, select() se na necem zasekne
jeste driv (zatim jsem nemel cas to zkoumat bliz).

	Cili zajima me, jak to ze kdyz mi poll()/epoll() rekne ze deskriptor
je pripraveny k zapisu, tak ve skutecnosti se zapis zablokuje? A co mam
delat pro to, aby se nezablokoval?

-Yenya

-- 
| Jan "Yenya" Kasprzak  <kas at {fi.muni.cz - work | yenya.net - private}> |
| GPG: ID 1024/D3498839      Fingerprint 0D99A7FB206605D7 8B35FCDE05B18A5E |
| http://www.fi.muni.cz/~kas/    Journal: http://www.fi.muni.cz/~kas/blog/ |
>>  If you find yourself arguing with Alan Cox, you’re _probably_ wrong.  <<
>>     --James Morris in "How and Why You Should Become a Kernel Hacker"  <<



Další informace o konferenci Linux