2009-05-26 14 views

Odpowiedz

1

Zdaję sobie sprawę z błędu w popularnym operacyjnego stacjonarnego gdzie O_NONBLOCK gniazda TCP, szczególnie te z systemem poprzez interfejs pętli zwrotnej, czasami może powrócić EAGAIN z recv() po select() raporty gniazdo jest gotowe do odczytu. W moim przypadku dzieje się to po tym, jak druga strona w połowie zamknie strumień nadawczy.

Aby uzyskać więcej informacji, zobacz kod źródłowy dla t_nx.ml w bibliotece NX mojej dystrybucji środowiska sieciowego OCaml. (link)

+1

Link wydaje się być uszkodzony – Thomas

+0

Zabawne, w menu edycji jest klikalne. :RE – thejh

2

jest to możliwe, ale tylko w sytuacji, gdy masz wiele wątków/procesów próbujących odczytać z tego samego gniazda.

+0

Cieszę się słyszeć. Moja aplikacja jest pojedyncza, więc nic mi nie jest. – mrvincenzo

4

Dla recv() otrzymasz EAGAIN zamiast EWOULDBLOCK, i tak jest to możliwe. Ponieważ właśnie sprawdzane select() następnie jedną z dwóch rzeczy się stało:

  • Coś innego (inny wątek) wycieknie bufora wejściowego między select() i recv().
  • Limit czasu odbioru został ustawiony na gnieździe i wygasł bez otrzymywania danych.
+0

W przypadku przekroczenia limitu czasu, select() zwraca 0, więc nie martwię się o to. – mrvincenzo

+3

#define EWOULDBLOCK EAGAIN/* Operacja będzie blokować */- znaleziona na wielu systemach – blaze

+0

POSIX.1-2001 pozwala na zwracanie błędów podczas odczytu na nieblokującym gnieździe (i nie wymaga, aby były takie same) value.) –

0

Jest to możliwe w środowisku wielowątkowym, w którym dwa wątki czytają z gniazda. Czy to jest aplikacja wielowątkowa?

+0

Jest to aplikacja z pojedynczym gwintem. – mrvincenzo

+0

Nawet jeśli na gnieździe jest limit czasu, a nie tylko parametr do 'select()'? Co się stanie, jeśli upłynie limit czasu między 'select()' a 'recv()'? – dwc

+0

W tym przypadku nie powinieneś widzieć tego zachowania. – mikelong

0

Jeśli nie wywołasz żadnego innego połączenia między select() i recv() na tym gnieździe, to recv() nigdy nie zwróci EAGAIN lub EWOULDBLOCK.

Nie wiem, co mają na myśli z recv-timeout, jednak standard POSIX nie wspomina o tym tutaj, więc można bezpiecznie wywoływać recv().

0

Chociaż moja aplikacja jest jednowątkowa, zauważyłem, że opisane zachowanie nie jest rzadkością w RHEL5. Zarówno z gniazdami TCP i UDP, które zostały ustawione na O_NONBLOCK (jedyna ustawiona opcja gniazda). select() informuje, że gniazdo jest gotowe, ale następujące polecenie recv() zwraca EAGAIN.

Powiązane problemy