2017-01-19 12 views
0

メインループがあり、いくつかの選択肢があるメニューを表示してユーザーの入力を待つ機能があります。
新しいイベントが発生するかどうかを確認する必要があります。- 特定のケースでは、新しいメッセージが届きましたが、これはまったく関連しません -と私はユーザーを待つことができません私はその機能のタイムアウトを実装する必要があります。ここで一定時間後にメインループ内の関数を中断します

は私が話しているかの簡単な例である:それはalarm()を通じてSIGALRM信号を受信した後

int choice; 

for(;;){ 

    /* a new message could be arrived and we should read it now ... */ 

    choice = menu_function(); 

    /* 
     ...but the user still hasn't made an action, 
     so the menu_function() hasn't returned yet. 
    */ 

    switch(choice){ 
     case 1: 
      break; 
     case 2: 
      break; 
     default: 
      break; 
    } 
} 

これまでのところ私はmenu_function()kill()fork()を使用しての、このプロセスを考えたが、私ドンそれがループ内にあるので、これが適切な解決策だとは思わない。

どのようなソリューションを採用しますか?

P.S.私はこれが重複しているとは思わない、既に言ったように、要求を中断する関数はループの中にある。少なくとも私にとっては違うと思います。

+0

[Cの関数のタイムアウトを設定するにはどうすればいいですか?](http://stackoverflow.com/questions/7738546/how-to-set-a-timeout-for-a-function-in- c) – iwaduarte

答えて

1

forkと書いてありますので、あなたはPOSIXシステム(LinuxやmacOSなど)を使用していると思いますか?

これは、待機中のプロセスでシグナルハンドラをSIGALRMにインストールすることができることを意味し、シグナルを受信すると、確認できるブロック動作(errno == EINTR)が中断され、menu_functionは "出口"。ループ内のコードがこの値をチェックし、ループ内でbreakをチェックできます。

もう1つの方法は、実際に何か読まない限り、標準のC入力関数を使用しないことです。これを行うには、希望のタイムアウトでselectコールを使用し、ポーリングFILENO_STDINを使用します。 select関数がタイムアウトで返された場合は、menu_functionに "exit"を意味する特別な値を返します。それ以外の場合は、標準C関数を使用して入力を読み込んで解析します。

入力ハンドラまたはタイマーのいずれかで新しいプロセスをフォークする必要はありません。

+0

ありがとう、それは私が探していたものです。私は試してみよう! – UrbiJr

+0

申し訳ありませんが、私はよく分からなかったと思います。 'SIGALRM'を受け取ったとき、' menu_function'からどのように値を返すことができますか?つまり、私は 'handle_sigalrm'関数を書いていますが、これをどうしたらいいのか分かりません。また、あなたが '休憩 'を言ったときに私は注意を払っていませんでした。どこで使うべきですか?例を作ることができれば - 私の例を正しいコードで埋めること - 私は確かあなたの答えを解決策としてマークしますが、今のところ私はまだまだ固執しています... – UrbiJr

+0

@UrbiJr 'scanf'は、文字が標準入力に到着するのを待って、' read'呼び出しにスタックされます。 'SIGALRM'を受け取ると、' read'呼び出しが中断され、中断された関数を再起動しないようにシグナルが初期化された場合、 'read'はエラーとともに返され、' errno'は 'EINTR'に設定されます。これはあなたに 'EOF'を返す' scanf'関数に渡されます。あなたの 'menu_function'が' scanf'を呼び出した場合、この条件をチェックして戻ります。シグナルハンドラ自体は何もする必要はありません。そのボディは空にすることができます。 –

関連する問題