2012-01-03 14 views
5

Używam Winsock pod VS 2008.odblokować Zablokowane Winsock accept() Zadzwoń

Mam wątek poświęcony przyjmowania przychodzących żądań połączeń TCP poprzez wywołanie blokującej zaakceptować(). Gdy nadejdzie czas zamknięcia mojej aplikacji, muszę jakoś odblokować ten wątek, aby mógł wykonać swoją pracę i zakończyć działanie. Czy istnieje sposób, w jaki mogę odblokować accept()?

Zamieścę kolejne pytanie na wypadek, gdyby nie było sposobu odblokowania accept(). Pytanie brzmi: jeśli wykonam ciężkie zabójstwo wątku zablokowanego w funkcji accept(), czy coś złego się stanie (uszkodzenie struktur danych systemu operacyjnego itp.)?

Dzięki Dave

+1

Nie możesz zamknąć gniazda, w którym jesteś zablokowany? Spowoduje to powrót 'accept()'. – tribeca

+0

IME, po prostu zamknięcie aplikacji, gdy funkcja accept() jest zablokowana, jest w porządku. System operacyjny wyczyści i nic się nie zepsuje. Jeśli naprawdę, absolutnie musisz jawnie wyczyścić, a następnie zamknąć gniazdo z innego wątku, jak sugerują inne plakaty. –

Odpowiedz

7

Jedynym sposobem odblokowania blokady accept() jest zamknięcie gniazda nasłuchu z innego wątku. W przeciwnym razie należy umieścić gniazdo nasłuchu w trybie bez blokowania i użyć select() (która obsługuje limit czasu), aby wykryć, kiedy można wywołać accept() bez blokowania.

+0

Uważam, że to rozwiązanie jest podatne na wyścig. Jest okno, w którym jeden wątek jest w pętli, ale poza 'select()', sprawdzając wartość zwracaną 'select()'; drugi wątek z powodzeniem wykonuje 'closesocket()'; trzeci wątek otwiera nowe gniazdo o tej samej wartości uchwytu; pierwszy wątek wznawia oczekiwanie w 'select()', ale teraz dla innego gniazda o tej samej wartości uchwytu. – wilx

+0

Jeśli użyjesz metody 'select()', o której wspomniałem, to drugi wątek nie musi wywoływać 'closesocket()'. Może po prostu ustawić sygnał, którego szuka pierwszy wątek, aby mógł zamknąć swoje własne gniazdo w najwcześniejszym dogodnym momencie. Użycie 'select()' gwarantuje, że pierwszy wątek nie jest blokowany w sposób nieokreślony w 'accept()', po prostu nie wywołując 'accept()' dopóki 'select()' mówi to. –

0

Jedno podejście mam stosowanych w przeszłości jest dostarczyć wartość limitu czasu dla zaakceptować() - a kiedy timesout, sprawdzić flagę „Anuluj” - jeśli ustawione, przestajesz - jeśli nie, wróć do pętli za pomocą funkcji accept().

Myślę, że zabicie wątku zadziała, ale powinieneś być ostrożny, aby upewnić się, że jest to twój wątek i na przykład wątek wątków .NET.

EDYTOWANIE: Remy ma rację, i myślę, że nawet zrobiłem szybki google, aby zweryfikować strukturę, którą pamiętam - wydaje się zbyt szybkie. Blush/itp.

Jeśli chcesz zachować semantykę blokującą, zobaczysz, jak zamknąć gniazdo z innego wątku (lub Przerwanie wątku blokującego).

+0

'accept()' w WinSock nie ma własnego parametru timeout. Musisz umieścić gniazdo nasłuchu w trybie bez blokowania, a następnie użyć 'select()' (które obsługuje limit czasu), aby wykryć, kiedy 'accept()' może być wywołane bez blokowania. –

+0

zabicie wątku jest znacznie bardziej kompletne, co wymagałoby zbyt wiele innych rzeczy do rozważenia. –

Powiązane problemy