Pregunta

Estoy intentando desarrollar un programa para el límite de tiempo de ejecución de una función. En el código de abajo tengo un Inc llamada, la cual realiza una gran cantidad de iteraciones (simulado por el bucle infinito). La primera parte de cada iteración es bastante largo, seguido de una segunda parte que debe ser bastante rápido.

no me importa adelantarse a la ejecución mientras que en la primera parte del código, pero me gustaría evitar la alarma que se apaga mientras se hace una operación de escritura en la segunda parte.

Mi primera idea era apagar la alarma antes de entrar en la 'zona segura' salvar el tiempo restante. A continuación, después de salir, me gustaría poner la alarma con el tiempo ahorrado. No sé cómo implementar esto. ¿Alguien podría ayudarme? Los métodos alternativos también son bienvenidos.

#include <pthread.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

pthread_t thread;
FILE *fout;

void *Inc(void *param){

    int i;
    long long int x = 0;

    fout = fopen("file.txt", "w");

    /* Large number of iterations */
    while(1){

        int k = 0;
        for(i=0; i<5000000; i++)
            k += (rand())%3;
        x += k;

        printf("%lld\n", x);
        /* Enter Safe Region */
        fprintf(fout, "%lld\n", x);
        /* Exit Safe Region */
    }   
}

void Finish(int param){
    pthread_cancel(thread);
    fclose(fout);
}

main (){

    pthread_attr_t attr;
    void *status;

    signal(SIGALRM, Finish);
    alarm(10);

    pthread_attr_init(&attr);
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);

    pthread_create(&thread, &attr, Inc, NULL);
    pthread_attr_destroy(&attr);
    pthread_join(thread, &status);

    printf("Program Finished\n");
}
¿Fue útil?

Solución

Lo obvio es tomar un bloqueo antes de llamar pthread_cancel, y para mantener el mismo bloqueo a través de su "zona segura".

Por desgracia, no se puede esperar en un mutex o un semáforo en un manejador de señales. Pero las señales de alarma no son la única manera de hacer algo después de 10 segundos - en su lugar podría tener su hilo principal Ir a dormir durante 10 segundos, luego despertar, tomar la cerradura, cancelar el subproceso de trabajo y luego unirse a ella

Por supuesto, esto significaría que el hilo principal va a dormir 10 segundos aunque los acabados de los subprocesos de trabajo después de 5 segundos. Así que en vez de dormir, tener el hilo principal hacer un segundo de espera temporizada 10 en un semáforo, que los puestos de los subprocesos de trabajo cuando se termine.

Al igual que un sueño, una espera temporizada puede terminar antes de tiempo debido a una señal, así que asegúrese de volver a intentar la espera temporizada en EINTR. Sus casos significativos son EINTR (esperar de nuevo), el éxito (unirse al subproceso de trabajo - no hay necesidad de cancelar ya que ha publicado el semáforo), ETIMEDOUT (tome el bloqueo, cancelación, se unen) y si te gusta, otros errores. No existen otros errores enumerados para sem_timedwait que debe afectar a usted, sin embargo.

Otra idea es bloquear SIGALRM a través de su "zona segura", lo que sería más simple, excepto que (a) Nunca puedo recordar cómo hacerlo de manera segura I / O con señales desactivado, y (b) el subproceso de trabajo probablemente podría ser correr "al mismo tiempo" con el manejador de la señal (ya sea verdaderamente simultánea o aparentemente tan debido a la preferente), lo que significa que la señal podría ser tomada, entonces su trabajador señales deshabilita y entra en la región crítica, entonces el manejador de señales cancela. Si no contesta, que en realidad pueden recordar los detalles, aquí hay algo de información sobre el bloqueo de señales .

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