Domanda

Sto cercando di sviluppare un programma per limite di tempo l'esecuzione di una funzione. Nel codice qui sotto ho una funzione denominata Inc che fa un sacco di iterazioni (simulata dal ciclo infinito). La prima parte di ogni iterazione è piuttosto lungo, seguita da una seconda parte che dovrebbe essere abbastanza veloce.

Non ho niente precludere l'esecuzione, mentre nella prima parte del codice, ma mi piacerebbe evitare l'allarme andando fuori mentre si fa un'operazione di scrittura sulla seconda parte.

La mia prima idea era quella di disattivare l'allarme prima di entrare nella 'zona di sicurezza' risparmiando il tempo rimanente. Poi, dopo l'uscita, vorrei impostare la sveglia con il tempo risparmiato. Non so come implementare questa. Qualcuno mi potrebbe aiutare? I metodi alternativi sono i benvenuti.

#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");
}
È stato utile?

Soluzione

La cosa più ovvia è quella di prendere un blocco prima di chiamare pthread_cancel, e di tenere lo stesso blocco in tutta la tua "zona sicura".

Purtroppo, non si può aspettare un mutex o di un semaforo in un gestore di segnale. Ma i segnali di allarme non sono l'unico modo per fare qualcosa dopo 10 secondi - si potrebbe invece avere il Thread Vai principale per il sonno per 10 secondi, poi svegliarsi, prendere la serratura, annullare il thread di lavoro e poi unirlo

Naturalmente questo significherebbe che il thread principale dormirà 10 secondi, anche se le finiture filo lavoratore dopo 5 secondi. Così, invece di dormire, avere il thread principale fare un secondo di attesa 10 a tempo su un semaforo, che i posti di filo lavoratore quando finisce.

Come un sonno, un'attesa temporizzata può completare in anticipo a causa di un segnale, in modo da essere sicuri di ripetere l'attesa temporizzata EINTR. I vostri casi significativi sono EINTR (aspettare di nuovo), il successo (join il thread di lavoro - non c'è bisogno di cancellare dal momento che ha pubblicato il semaforo), ETIMEDOUT (prendere la serratura, si annullano, si uniscono) e se vi piace, altri errori. Non ci sono altri errori elencati per sem_timedwait che dovrebbero influenzare voi, però.

Un'altra idea è quella di bloccare SIGALRM attraverso la vostra "zona sicura", che sarebbe più semplice se non che (a) non riesco mai a ricordare come farlo in modo sicuro di I / O con i segnali disabilitato, e (b) il tuo thread di lavoro potrebbe probabilmente essere esecuzione "simultaneamente" con il gestore di segnale (sia veramente simultanea o apparentemente così a causa di prelazione), il che significa che il segnale potrebbe essere presa, quindi i vostri lavoratori disabilita i segnali ed entra nella regione critica, quindi il gestore di segnale lo annulla. Se nessuno risponde che può effettivamente ricordare i dettagli, ecco alcune informazioni sui bloccando i segnali .

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top