1

I'm trying to create a program where the user is asked a question and has a few seconds to answer the question, or else the program stops input.

Now my problem is I'm unable to get my program not to block input. I am able to input data, but when I don't and the timer runs out it keeps asking for input.

I'm running on Windows and use Code::Blocks in case it's important. If someone could explain to me what I'm doing wrong, it would be appreciated.

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <pthread.h>
#include <conio.h>

int key = 0;
int GradeTotal = 0;

//runs an empty loop every iteration F.E. for loop
void timer(int seconds)
{
    clock_t wait = (clock() + (seconds * CLOCKS_PER_SEC));
    while(clock() < wait){}

}

void timeleft()
{
    int index;

    for(index = 5; index >= 0; index--)
    {
        if(key != 0)
        {
            pthread_exit(timeleft);
        }

        timer(1);

        if(index == 0)
        {
        printf("\n\nTime's up!");
        }
    }
}

void questions()
{
    int key;

    printf("what is 1 + 1?\nAnswer: ");

    while(1)
    {
        if(_kbhit())
        {
            key = _getch();
            printf("%c",key);
            break;
        }
    }
    if(key == 50)
    {
         GradeTotal += 1;
    }  
 }


int main()
{
    pthread_t thread1,thread2;

    int index;
    int seconds = 0;
    pthread_create(&thread1, NULL, questions, NULL);
    pthread_create(&thread2, NULL, timeleft, NULL);
    pthread_join(thread1, NULL);
    pthread_join(thread2, NULL);

    printf("\n\nGrade: %d",GradeTotal);

    return 0;
}
4
  • 1
    while(clock() < wait){} god damn you want destroy my heart ? Use something like sleep() Commented Dec 29, 2017 at 11:31
  • Some question : stackoverflow.com/questions/28382962/… Commented Dec 29, 2017 at 11:33
  • suggest using: select() with a timeout value, then when the call to select() returns, check if it was due to an error, or due to a timeout, or due to stdin being ready with data, This will still block the thread that it is in, so place it in a separate thread. Commented Dec 30, 2017 at 5:07
  • suggest using a call to setitimer() and using the appropriate signal handler to catch the expiration of the timer. Commented Dec 30, 2017 at 5:11

2 Answers 2

1

When time ran out have timeleft() set a global flag, which is tested by questions(), and if set makes the code leave the while (1) loop.

Make sure access to the flag is protected using a mutex.

Talking about "protected access": key is accessed concurrently without protection. Not good.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks! got it to work now with a global variable checking index's status like you suggested.
1

This exemple use pthread's feature to set up a timer and cancel the thread if something goes wrong, I didn't check any error in this exemple. In real application, you must do it:

#include <stdio.h>
#include <pthread.h>
#include <time.h>

void *wrapper_handle_question(pthread_cond_t *cond) {
  char buf[2048];
  size_t i = fread(buf, 1, sizeof buf - 1, stdin);
  buf[i] = '\0';
  printf("%s", buf);
  pthread_cond_broadcast(cond);
  return NULL;
}

void *handle_question(void *arg) { return wrapper_handle_question(arg); }

int main(void) {
  pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
  pthread_t question;
  pthread_create(&question, NULL, &handle_question, &cond);

  struct timespec ts;
  clock_gettime(CLOCK_REALTIME, &ts);
  ts.tv_sec += 5;

  pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
  pthread_mutex_lock(&mutex);

  int rc = pthread_cond_timedwait(&cond, &mutex, &ts);
  pthread_mutex_unlock(&mutex);
  if (rc == 0) {
    pthread_join(question, NULL);
  } else {
    pthread_cancel(question);
    printf("timeout!\n");
  }
}

1 Comment

Being picky: POSIX does not require fread() to be a cancellation point.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.