2012-01-03 12 views
5

estoy usando Winsock bajo VS 2008.desbloquear un Winsock Bloqueado aceptar() Llame a

tengo un hilo dedicado a aceptar solicitudes de conexión TCP entrantes a través de una llamada de bloqueo de aceptar(). Cuando llegue el momento de que mi aplicación se cierre, necesito desbloquear este hilo de alguna manera para que pueda realizar su cierre y salir. ¿Hay alguna manera de desbloquear accept()?

Voy a publicar otra pregunta en caso de que no haya forma de desbloquear accept(). Esa pregunta es: si realizo una eliminación definitiva del hilo que está bloqueado en accept(), ¿pasará algo malo (corrupción de las estructuras de datos del sistema operativo, etc.)?

Gracias, de Dave

+1

¿No puedes cerrar el socket en el que estás bloqueado? Esto hará que 'accept()' regrese. – tribeca

+0

IME, acaba de salir de la aplicación mientras que accept() está bloqueado está bien. El sistema operativo se limpiará y nada se romperá. Si realmente, absolutamente tiene que limpiar explícitamente, luego cierre el socket de otro hilo, como lo sugieren otros carteles. –

Respuesta

7

La única forma de desbloquear un bloqueo accept() es cerrar el puerto de escucha de otro hilo. De lo contrario, debe colocar el puerto de escucha en modo sin bloqueo y usar select() (que sí admite un tiempo de espera) para detectar cuándo se puede llamar al accept() sin bloqueo.

+0

Creo que esta solución es propensa a una carrera. Hay una ventana donde un hilo está en un bucle pero fuera de 'select()', verificando el valor de retorno 'select()'; segundo subproceso con éxito hace 'closesocket()'; tercer hilo abre un nuevo socket con el mismo valor de manejo; el primer hilo se reanuda esperando en 'select()' pero ahora para un socket diferente con el mismo valor de handle. – wilx

+0

Si usa el enfoque 'select()' que mencioné, entonces el segundo hilo no necesita llamar 'closesocket()'. Simplemente puede establecer una señal que busque el primer subproceso para que pueda cerrar su propio socket lo antes posible. El uso de 'select()' asegura que el primer hilo no se bloquea indefinidamente en 'accept()', simplemente no se llama a 'accept()' hasta que 'select()' responde a. –

0

Un método que he utilizado en el pasado es suministrar un valor de tiempo de espera para aceptar() - y cuando timesout, se comprueba una bandera "cancelar" - si está ajustado, detienes; si no, vuelves al ciclo con la llamada a accept().

Creo que matar el hilo funcionaría, pero debe tener cuidado de asegurarse de que sea su hilo y, por ejemplo, no un hilo .NET thread.

EDIT: Remy tiene razón, y pensar que incluso hice un google rápido para verificar que existe la estructura que recuerdo, demasiado rápido, parece. Blush/etc.

Si quiere mantener la semántica de bloqueo, vería cerrar el socket de otra cadena (o Anulando su cadena de bloqueo) sería el camino a seguir.

+0

'accept()' en WinSock no tiene un parámetro de tiempo de espera propio. Debe poner el conector de escucha en modo no bloqueante y luego usar 'select()' (que admite un tiempo de espera) para detectar cuándo se puede invocar 'accept()' sin bloqueo. –

+0

matar el hilo es mucho más completo, eso implicaría demasiadas cosas más que hay que considerar. –

Cuestiones relacionadas