2017-12-29 31 views
0

Ich versuche ein Programm zu erstellen, in dem der Benutzer eine Frage gestellt bekommt und ein paar Sekunden hat, um die Frage zu beantworten, sonst bricht das Programm die Eingabe ab.Nicht blockierender Eingang C

Jetzt ist mein Problem, ich bin nicht in der Lage, mein Programm nicht zu blockieren, um die Eingabe zu blockieren. Ich kann Daten eingeben, aber wenn ich nicht weiß und der Timer abläuft, fragt er nach Eingabe.

Ich verwende Windows und verwende Code :: Blocks, falls es wichtig ist. Wenn jemand mir erklären könnte, was ich falsch mache, würde es geschätzt werden.

#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

'while (Uhr() Stargateur

+0

Einige Frage: https://stackoverflow.com/questions/28382962/wait-for-press-enter-in-c-inside-a-while-loop –

+0

schlagen vor mit: 'wählen () 'mit einem Timeout-Wert, dann, wenn der Aufruf von' select() 'zurückkehrt, überprüfen Sie, ob es aufgrund eines Fehlers war, oder aufgrund einer Zeitüberschreitung, oder weil stdin bereit mit Daten ist es ist in, also lege es in einen separaten Thread. – user3629249

Antwort

1

Wenn die Zeit ran out timeleft() eine globale Flag gesetzt, die von questions() geprüft wird, und wenn Set macht den Code verlassen die while (1) Schleife.

Stellen Sie sicher, dass der Zugriff auf das Flag durch einen Mutex geschützt ist.

Über "geschützten Zugriff" sprechen: key wird gleichzeitig ohne Schutz zugegriffen. Nicht gut.

+0

Danke! habe es jetzt mit einem globalen Variablenüberprüfungs-Index-Status wie von dir vorgeschlagen funktionieren lassen. – SpicyUsername

1

Dieses Beispiel verwenden pthread-Funktion, um einen Timer einzurichten und den Thread abzubrechen, wenn etwas schief geht, ich habe keinen Fehler in diesem Beispiel überprüft. In der realen Anwendung müssen Sie es tun:

#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

Wählerisch: POSIX benötigt * nicht * fread() ', um einen Löschpunkt zu sein. – alk

Verwandte Themen