2010-03-21 11 views
7

Tengo un bucle que se pide básicamente esto cada pocos segundos (después de que el tiempo de espera):estallido de la toma de seleccionar

while(true){ 

    if(finished) 
     return; 

    switch(select(FD_SETSIZE, &readfds, 0, 0, &tv)){ 
     case SOCKET_ERROR : report bad stuff etc; return; 
     default : break; 
    } 

    // do stuff with the incoming connection 
} 

Así que, básicamente, para cada pocos segundos (que se especifica por tv), reactiva la escucha .

Esto se ejecuta en el hilo B (no en el hilo principal). Hay momentos en los que quiero terminar este bucle de aceptación inmediatamente desde el hilo A (hilo principal), pero parece que tengo que esperar hasta que termine el intervalo de tiempo ...

¿Hay alguna manera de interrumpir la función de selección de otro hilo? ¿Entonces el hilo B puede salir al instante?

+0

Nota: puede cortar el enunciado if y simplemente escribir mientras (! Terminado). –

+0

Eso tomará 100% de tiempo de CPU sin embargo. Definitivamente no es aceptable. – kamziro

+0

whoops, debo haber leído mal que – kamziro

Respuesta

9

La manera más fácil es probablemente usar pipe(2) para crear una tubería y agregar el extremo de lectura a readfds. Cuando el otro subproceso quiere interrumpir el select(), simplemente escríbele un byte, luego cómprelo después.

+0

Es un socket de escucha (uno que acepta conexiones). ¿Esto todavía funciona? Estaba pensando en llamar a alguna función que destruya el socket ... para ver qué pasa. ¿Esto sería seguro? – kamziro

+1

Está esperando el archivo * a *. No le importa * qué *, solo quiere * algo *. –

+0

¡Funcionó, y aprendí una o dos cosas con las tuberías de Unix! ¡Gracias! Por cierto, todo lo que estoy haciendo después de la interrupción es salir del programa. así que no me molesto en consumir. Está bien, ¿verdad? – kamziro

3

Sí, crea un par de enchufes conectados. Luego, el hilo B escribe en un lado del zócalo y el hilo A agrega el otro zócalo lateral para seleccionar. Así que una vez que B escribe en el socket A, seleccione seleccionar, no olvide leer este byte del socket.

Esta es la forma más estándar y común de interrumpir selecciones.

Notas:

En Unix, utilice socketpair para crear un par de tomas de corriente, debajo de las ventanas es poco complicado, pero buscando en Google para Windows socketpair le daría muestras de código.

+0

Ah, acabo de utilizar el tubo (2) y parece que funciona . Debo preocuparme por su homólogo de ventana eventualmente ... – kamziro

-1

¿No puedes simplemente hacer que el tiempo de espera sea lo suficientemente corto (como 10 ms o menos?).

Estos "acaba de crear una conexión ficticia" tipo de solución parecen una especie de hackeado. Personalmente, creo que si una aplicación está bien diseñada, las tareas concurrentes nunca tienen que interrumpirse con fuerza, simplemente el trabajador tiene suficiente control (esta es también una razón por la cual boost.threads no tiene una función de terminación).

Editar Hecho esta respuesta CV. Es malo, pero podría ayudar a otros a entender por qué es malo, lo que se explica en los comentarios.

+1

-1 Esta es una solución muy mala que solo cuesta CPU y aún tiene problemas de retraso. Hay soluciones estándar para esto. – Artyom

+0

¿Cómo le cuesta eso a la CPU? ¿Qué son 10 ms de espera para la CPU en comparación con la creación de una conexión de socket ficticia? –

+1

El costo de la CPU es reducir el tiempo de espera, haciendo que el bucle se ejecute con más frecuencia. – caf

-1

Puede usar shutdown (Sock, SHUT_RDWR) llamada desde el hilo principal para salir de la llamada de espera de espera, que también saldrá de su otro hilo antes del tiempo de espera para no tener que esperar hasta que expire el tiempo de espera.

aplausos. :)

+1

Desafortunadamente, no se puede 'apagar 'un socket de escucha. Y no hay una forma segura de "cerrarlo" mientras otro hilo está, o podría estar, usándolo. –

+0

Si tiene una función de hilo de socket que se menciona a continuación y si envía shutdown (calcetín, SHUT_RD) desde el hilo principal, se activará esperando una llamada de SockThreadFunction ejecutándose en otro hilo. Lo he intentado y está funcionando bien. SockThreadFunction() {while (SocketOpen) {// En espera de Seleccionar llamada int Ready = select (pSocket-> m_Sock + 1, & SockSet, 0, 0, 0); } –

+0

Tiene un conector para escuchar. No se puede 'apagar' un socket de escucha. Funcionará para enchufes conectados, pero no funcionará para un socket de escucha, que es lo que tiene. –

Cuestiones relacionadas