lundi 27 juin 2016

Busy-waiting thread not terminating in C++

I'm creating a simple application which has four threads that do various timer functions:

  1. Keep track of and print current time (working)
  2. Timer thread which terminated all threads when timer is complete (issue)
  3. Alarm thread which displays an alarm at a specified time (working)
  4. Busy-wait thread which terminates all threads upon user input (sort of working)

The issue with the timer thread not actually killing all four threads. I have verified and tested that threads 1-3 are terminated, but the fourth thread isn't being terminated when the timer runs out, but does terminate if I type x into the console. I need to gracefully terminate all threads (i.e. no SIGINT) for whichever event comes first. To restate, if I type x into the console the process will terminate as expected.

Relevant info:

static pthread_t threads[MAX_THREADS];
static sem_t FLAG;
static bool quit, timer_quit;

int main(int argc, char** argv) {
    sem_init(&FLAG, 0, 1);

    // initialize/check thread status for all four threads

    pthread_exit(NULL);
}

Threads 2 and 4 have the following callbacks:

void* countdown_callback(void* seconds) {
    for(int i = (int) seconds; i >= 0; i--) {
        sem_wait(&FLAG);
        if(quit) break; // check to see if user typed 'x'
        sem_post(&FLAG);

        sleep(1);
    }

    sem_wait(&FLAG);
    if(!quit && !timer_quit) timer_quit = true;
    sem_post(&FLAG);

    pthread_exit(NULL);
}

void* keyboard_callback(void* keypress) {
    while(getch() != 'x') {
        sem_wait(&FLAG); // never hit
        if(timer_quit) {
            sem_destroy(&FLAG);
            std::cout << "Timer ran out, program exiting!rn";
            pthread_exit(NULL);
        }
        sem_post(&FLAG);
    }

    sem_wait(&FLAG);
    quit = true;
    sem_destroy(&FLAG);

    std::cout << "Exiting the programrn";
    pthread_exit(NULL);
}

As stated previously, it looks like threads 1-3 terminate when debugging with gdb. I can see all three threads hit pthread_exit by setting breakpoints. The issue is the sem_wait in the keyboard callback is never hit I have no idea why. I've played around with moving sem_wait and tried my best to ensure I am releasing the semaphore when I'm done using it, but this thread continues to run.

Note:

Aucun commentaire:

Enregistrer un commentaire