Pregunta

Tengo que llamar a una función de biblioteca que a veces no va a terminar en un tiempo determinado, por desgracia. ¿Hay una manera de llamar a la función, pero abortar si no termina en cuestión de segundos n?

No puedo modificar la función, así que no puedo poner la condición de interrupción en ella directamente. Tengo que añadir un tiempo de espera a la función externa .

¿Es tal vez una posible solución para iniciarlo como un hilo (impulso), que luego puede terminar después de un cierto tiempo? Sería algo así trabajar? De hecho, creo que la función es no seguro para subprocesos, pero eso no importa si lo ejecuto como el solamente solo hilo, ¿verdad? ¿Hay otras soluciones (mejores)?

¿Fue útil?

Solución

Se podría generar una boost::thread a llamar a la API:

boost::thread api_caller(::api_function, arg1, arg2);
if (api_caller.timed_join(boost::posix_time::milliseconds(500)))
{
    // API call returned within 500ms
}
else
{
    // API call timed out
}

Boost no permite que mates el subproceso de trabajo, sin embargo. En este ejemplo, sólo es huérfano.

Vas a tener que tener cuidado con lo que hace que la llamada a la API, porque nunca puede liberar los recursos que ha adquirido.

Otros consejos

Creo que la única forma segura de lograr esto sería la de generar un caja de arena proceso separado que llama a la función de la biblioteca como un proxy para su aplicación. Tendrá que aplicar algún tipo de IPC entre la aplicación y el proxy. La implementación de un tiempo de espera al leer la respuesta del IPC es entonces bastante trivial. Si la lectura falla debido a tiempo de espera, a continuación, puede terminar de forma segura el proxy sin poner en riesgo la salud de su aplicación.

Lo que está hablando normalmente se llama un sistema de "perro guardián". El organismo de control es típicamente un segundo hilo que comprueba en el estado de todos los otros hilos. El organismo de control normalmente está configurado para ejecutarse periódicamente. Si no hay respuesta se ha recibido de los otros hilos, el organismo de control puede notificar al usuario, o incluso matar el hilo infractor si es posible hacerlo de forma segura (depende de la aplicación).

El problema con las discusiones es que algunos recursos que no serán capaces de liberar después de la terminación hilo. Si usted no adquiere los recursos que usted tiene que liberar y luego ir con hilos.

El problema es que con una solución en proceso sin el apoyo de la función se termina con el estado podría no ser válido.

Ejemplo:. Cuando se termina el hilo, mientras que una asignación de memoria se lleva a cabo, el montón de proceso puede estar dañado

Así que es posible terminar la llamada, pero luego también hay que terminar el proceso. En muchos casos, las posibilidades de efectos secundarios destructivos son pequeñas, pero yo no apostaría mi cómputo en eso.

Se puede, como sugiere Ben Straub, simplemente huérfanos del hilo: lo puso en la prioridad más baja y se deja correr para el infinito. Eso es, por supuesto, sólo una solución limitada: si el hilo consume Recursos (probable), que se ralentizará el sistema, también hay un límite en las roscas por proceso (por lo general debido a espacio de direcciones de pila de subprocesos)

.

En general, prefiero la solución de proceso externo. Un modelo simple es la siguiente:
Escribir datos de entrada en un archivo, iniciar el proceso externo con el archivo como argumento. El proceso externo escribe curso (si los hay) a un archivo de disco que se puede controlar, e incluso puede permitir que el proceso para reanudar desde donde se inició. Los resultados se escriben en el disco, y el proceso padre puede leer en.

Al terminar el proceso, usted todavía tiene que hacer frente a sincronizar el acceso a Recursos externos (como archivos), y la forma de lidiar con mutices abandonados, los archivos a medio escribir, etc. pero es generalmente la forma de una solución sólida.

Lo que necesita es un hilo y una rel="nofollow futuro Objeto que no retienen el el resultado de la llamada a la función.

En un ejemplo utilizando impulso ver aquí .

Usted tendría que comprobar el futuro tras el tiempo de espera y si no se establece, actuar en consecuencia.

Vaya con un proceso huérfano, lanzarlo y el tiempo de su ejecución. Si se le acaba el tiempo, invocar el sistema operativo para acabar con él.

¿Cómo evitar conds carrera. en este patrón:

  • crear un archivo para almacenar en args (por supuesto, todo lo que se transmite como Vals). El proceso huérfano sólo se le permite leer los datos de este archivo.

  • La huérfana procesa los datos de entrada, crea un archivo de salida con valores de resultado y lo cierra.

  • Sólo cuando todo está hecho, huérfana borra el archivo de entrada, un hecho que señala el proceso maestro que el trabajo estaba hecho.

Esto evita la lectura de un medio escrito de problemas de archivos, ya que los primeros avisos maestros ausencia de archivo de entrada, se abre para leer el archivo de salida, lo que sin duda se ha completado (porque se cerró antes de borrar la entrada, y las pilas de llamadas OS son secuenciales).

"Tengo que llamar a una función de biblioteca que a veces no va a terminar en un tiempo determinado, por desgracia. ¿Hay una manera de llamar a la función, pero abortar si no termina en n segundos?"

La respuesta corta es no. Eso es por lo general problemas ... La llamada en sí debe terminar en algún momento (implementando su propio tiempo de espera), pero llamadas de bloqueo son generalmente problemas (por ejemplo, gethostbyname ()) porque entonces le toca a su (o sistema) de tiempo de espera, no la suya.

Por lo tanto, siempre que sea posible tratar de hacer que el código que se ejecuta en la salida de rosca limpia cuando sea necesario - el propio código debe detectar y controlar el error. Se puede enviar un mensaje y / o estados de regulación para que el principal (o aother) hilo sabe lo que pasó.

Las preferencias personales, en los sistemas de alta disponibilidad, me gusta que mis hilos girando a menudo (sin embargo ocupado-bloqueo) con tiempos de espera específicas, llamadas a funciones no bloqueantes, y con condiciones de salida precisos en su lugar. Una variable global o hilo específico 'hecho' hace el truco para una salida limpia.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top