2

だからここに私のコードがあります:

void sigHandle(int sig)
{
    signal(SIGINT, sigHandle);    //Is this line necessairy?
    cout<<"Signal: "<<sig<<endl;    
}

int main(){

    signal(SIGINT, sigHandle);

    while(true){ //Supposed to loop until user exits.

    //rest of my code
    
    }
}

SIGINTコマンド(Ctrl+C右?)を受信すると、関数sigHandleを整数値2(SIGINT番号)で呼び出す必要があり、メソッドが実行され、プログラムが終了しないことが、signal()についての私の理解です。

信号番号を印刷して先に進むだけですが、「Signal:2」を印刷すると終了します。

(最終的には最初の32個の割り込みを処理することになっていますが、 Ctrl+Cが最も難しいと考えたので、ここから始めます。)

主に、signal(SIGINT、SIG_IGN);を実行する場合。シグナルを正しく無視して終了しませんが、SIGINT割り込みを受信したかどうかを知る方法がありません。

以前、私はsigaction構造体で遊んでいましたが、実際の包括的なドキュメントが見つからなかったため、「生の」信号処理だけを使用することにしました。

これは私のシグアクションコードでした(上記と同じ問題):

struct sigaction action;
action.sa_handler = sigHandle;
sigemptyset(&action.sa_mask);
action.sa_flags = 0;
sigaction(SIGINT, &action, 0);

ご協力いただきありがとうございます!

編集

OK SOマニュアルページとインターネットを何時間も調べた後、スタックの無限ループを保存し、割り込みが発生したときに、必要なことを実行してから再設定するという(非常に)ゲットーの解決策に出くわしました。スタックを元の場所に戻し、sigrelse()コマンドを呼び出して、変更されて再ロードされなかった可能性のある状態をリセットします。

私はこれがこの問題に対する最もエレガント/効率的/または社会的に受け入れられる解決策ではないことを理解していますが、それは機能し、私が知る限り、どこにもメモリが漏れていないので、それはすべて良いです...

私はまだこの問題の解決策を探しています、そして私は私のスタックがシェナニギンを再設定することを一時的な修正としてのみ見ています...

ありがとう!

4

2 に答える 2

0

また、シグナル ハンドラで stdio (またはその他の再入不可関数) を呼び出さないでください。(シグナル ハンドラーは、malloc の途中で呼び出されるか、C++ に相当するものである可能性があります)

于 2011-09-30T13:49:18.923 に答える
0

そうではない。SIGINTのハンドルを同じ機能に置き換えるだけです。待機をどのようにプログラムしますか?

次のようなものがある場合:

int main
{ 
 // ...

  int r = read(fd, &buff, read_size); // your program hangs here, waiting for the data.
                                      // but if signal occurred during this period of time
                                      // read will return immediately, and r may != read_size

  return 0;  // then it will go straight to return.
}
于 2011-09-30T13:44:16.773 に答える