Non blocking input C

一个人想着一个人 提交于 2019-12-11 12:18:47

问题


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;
}

回答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.




回答2:


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");
  }
}


来源:https://stackoverflow.com/questions/48021828/non-blocking-input-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!