Frage

Ich versuche, die Ausführung einer Funktion ein Programm zur Zeitbegrenzung zu entwickeln. Im folgenden Code Ich habe eine Funktion namens Inc, die eine Menge von Iterationen tut (durch die Endlosschleife simuliert). Der erste Teil jeder Iteration ist ziemlich lang, von einem zweiten Teil folgte die ziemlich schnell sein sollte.

Ich habe nichts dagegen, die Ausführung, während im ersten Teil des Codes preempting, aber ich möchte der Alarm abgehend vermeiden, während eine Schreiboperation auf dem zweiten Teil zu tun.

Meine erste Idee war es, den Alarm auszuschalten, bevor Sie den ‚sicheren Bereich‘ Eingabe der verbleibenden Zeit zu sparen. Dann nach dem Verlassen würde ich den Alarm mit der gespeicherten Zeit. Ich weiß nicht, wie dies zu implementieren. Könnte mir jemand helfen? Alternative Methoden sind auch willkommen.

#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");
}
War es hilfreich?

Lösung

Die offensichtliche Sache ist, eine Sperre zu nehmen, bevor pthread_cancel Aufruf und die gleiche Sperre in Ihrem „sicheren Bereich“ zu halten.

Leider kann man nicht auf einem Mutex warten oder eine Semaphore in einem Signal-Handler. Aber Alarmsignale sind nicht der einzige Weg, um etwas nach 10 Sekunden zu tun - Sie stattdessen Ihre Haupt-Thread zu schlafen für 10 Sekunden haben könnte, dann aufwachen, nehmen Sie die Sperre, brechen Sie den Worker-Thread und dann beitreten

Natürlich würde dies bedeuten, dass der Haupt-Thread 10 Sekunden, selbst wenn die Arbeiter-Thread beendet nach 5 Sekunden schlafen. Also anstatt zu schlafen, hat den Haupt-Thread tun, um eine 10 Sekunden zeitlich Warten auf einer Semaphore, die die Arbeiter-Thread Beiträge, wenn es fertig ist.

Wie ein Schlaf, kann eine zeitlich Warte vervollständigen früh aufgrund eines Signals, so sicher sein, die zeitlich Warten auf EINTR erneut zu versuchen. Ihre bedeutende Fälle sind EINTR (warten wieder), Erfolg (kommen Sie mit den Worker-Thread - keine Notwendigkeit zu löschen, da sie die Semaphore geschrieben hat), ETIMEDOUT (nehmen Sie die Sperre aufheben, verbinden), und wenn Sie möchten, andere Fehler. Es gibt keine weiteren Fehler für sem_timedwait aufgeführt, die Sie betreffen sollte, though.

Eine weitere Idee ist SIGALRM in Ihrem „sicheren Bereich“ zu blockieren, was außer dass einfacher wäre, (a) Ich kann nie mehr, wie sicher ich tun / O-Signale deaktiviert, und (b) Ihr Arbeitsthread könnte wahrscheinlich sein läuft „gleichzeitig“ mit den Signal-Handler (entweder wirklich gleichzeitigen oder scheinbar so aufgrund Vorkaufsrecht), was bedeutet, dass das Signal genommen werden kann, dann bricht es Ihre Arbeiter deaktiviert Signale und tritt in dem kritischen Bereich, wurde die Signal-Handler. Wenn niemand antwortet, die die Details wirklich erinnern kann, hier einige

scroll top