6

始める前に、これがコマンド ライン ツールではなく、独自のコマンド ライン インターフェイスを介してコマンドを受け取るアプリケーションであることを明確にしておきます。

編集:以前の説明についてお詫びしなければなりません。明らかに、説明がうまくできていませんでした。もう1回...

ユーザーからのコマンドを受け入れるコマンドライン インターフェイス アプリケーションを構築しています。シグナルをキャッチするシグナル ハンドラーをセットアップし、アプリケーションを終了するために必要なフラグを設定します。私が抱えている問題は、見つけることができるすべてのコンソール機能がブロックされていることです。つまり、ユーザーがキーを押すまで (または機能によっては入力するまで)、コンソール処理ループを終了する必要があることを検出できません。 )。

非ブロックコンソール対話を行うことができる標準的な方法はありますか、またはシグナルスレッドから終了するだけですべてが適切に処理および解放されるようにプログラムを構成するエレガントな方法はありますか (誤解しないでください) -これを理解してください。シグナリングスレッドからリソースをロックおよび解放することでこれを行う方法は知っていますが、これは面倒になる可能性があるため、むしろ避けたいと思います)

うまくいけば、その説明はより理にかなっています...

4

5 に答える 5

8

OK - これは Windows で動作し、移植可能です - #ifdef SIGBREAK に注意してください - これは標準のシグナルではありません。

#include <csignal>
#include <iostream>
#include <ostream>
#include <string>
using namespace std;

namespace
{
    volatile sig_atomic_t quit;

    void signal_handler(int sig)
    {
        signal(sig, signal_handler);
        quit = 1;
    }
}

int main()
{
    signal(SIGINT, signal_handler);
    signal(SIGTERM, signal_handler);
#ifdef SIGBREAK
    signal(SIGBREAK, signal_handler);
#endif
    /* etc */

    while (!quit)
    {
        string s;
        cin >> s;
        cout << s << endl;
    }
    cout << "quit = " << quit << endl;
}
于 2008-10-08T06:54:55.850 に答える
6

*nix では、signal関数を使用してシグナル ハンドラを登録できます。


#include <signal.h>

void signal_handler(int sig)
{
  // Handle the signal
}

int main(void)
{
  // Register the signal handler for the SIGINT signal (Ctrl+C)
  signal(SIGINT, signal_handler);
  ...
}

これで、誰かがCtrl+を押すたびCに、シグナル ハンドラーが呼び出されます。

于 2008-10-08T05:07:21.310 に答える
3

Windows の場合: SetConsoleCtrlHandler

于 2008-10-08T05:05:46.010 に答える
1

* nixベースのシステムでは、これが機能するためにシグナルハンドラーは実際には必要ない場合があります。SIGINT呼び出しを無視するように指定できます

int main(void)
{
  // Register to ignore the SIGINT signal (Ctrl+C)
  signal(SIGINT, SIG_IGN);

  while(1)
  {
    retval = my_blocking_io_func();
    if(retval == -1 && errno == EINTR)
    {
      // do whatever you want to do in case of interrupt
    }
  }
}

これが機能する重要な方法は、非ブロッキング機能が中断されることを認識することです。通常、ブロッキング関数が失敗したことに気づき(たとえば、read())、関数を再試行します。それが他の値である場合は、適切なエラー関連のアクションを実行します。

于 2008-10-08T05:28:40.737 に答える