2017-12-29 40 views
0

ユーザーに質問があり、質問に答えるのに数秒かかるプログラムを作成しようとしています。そうでないとプログラムは入力を停止します。ノンブロッキング入力C

私の問題は、私のプログラムが入力をブロックしないようにすることができないことです。 私はデータを入力することができますが、入力しないとタイマーが切れると入力を要求し続けます。

私はWindows上で動作しており、Code :: Blocksを使用することが重要です。 誰かが私に何が間違っているのか説明することができれば、それは感謝します。時間timeleft()questions()によって試験されたグローバルフラグを設定し、設定コードを行う場合た使い果たし

#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(clock() Stargateur

+0

いくつか質問があります:https://stackoverflow.com/questions/28382962/wait-for-press-enter-in-c-inside-a-while-loop –

+0

は ' ) 'にタイムアウト値を設定した場合、' select() 'の呼び出しが返ってきたときにエラーが発生したか、タイムアウトか、stdinがデータを準備できているかどうかをチェックします。それが入っているので、別のスレッドに配置してください。 – user3629249

答えて

1

while (1)ループを残します。

フラグへのアクセスがmutexを使用して保護されていることを確認してください。

「保護されたアクセス」について:keyは、保護なしで同時にアクセスされます。良くない。

+0

ありがとう!あなたが提案したようにグローバル変数のチェックインデックスのステータスで今すぐ動作するようになりました。 – SpicyUsername

1

この例では、pthreadの機能を使用してタイマーを設定し、問題が発生した場合にスレッドをキャンセルします。この例ではエラーをチェックしませんでした。実際のアプリケーションでは、あなたはそれをしなければなりません:

#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

気難しいこと:POSIXでは、* fread()がキャンセルポイントである必要はありません。 – alk