4

デーモンとして実行中の私のプロセス。シグナルを使用して構成をリロードしたい。問題は、構成が間違っている場合、送信されたシグナルの tty 形式でエラー メッセージが表示されることです。

  1. これを行う方法はありますか?
  2. おすすめの方法は?

それが推奨されない方法である場合。成功したかどうかを確認するより適切な方法は何ですか?

4

4 に答える 4

6

シグナル ソースの pid を取得するには、シグナル ハンドラを設定するときsa_sigactionの代わりに使用する必要があります。sa_handler

static pid_t g_killer_pid = 0;

static void signal_handler( int num, siginfo_t *info, void* blabla )
{
    g_killer_pid = info->si_pid;
}

int main(void)
{    
    struct sigaction sa;

    memset( &sa, 0, sizeof(sa) );
    sa.sa_sigaction = &signal_handler;
    sa.sa_flags = SA_SIGINFO;
    sigaction( SIGTERM, &sa, NULL );
    sigaction( SIGINT,  &sa, NULL );

    pause();
    hello_killer( g_killer_pid );

    return 0;
}

これで、ソース プロセスの pid が得られました。

ソース プロセスの端末 ID を取得するのは簡単ではありません。proc/<pid>/stat1 つの方法は、ファイルから読み取ることです。ファイル内の 1 つの番号はtty_nr. tty_nr私にとっては少し奇妙なので、これがポータブルなものであるかどうかはわかりません。ただし、書き込み用に正しい端末を開くために使用できるマイナー番号を保持しています。

static void hello_killer( pid_t killer )
{
    char filename[200];
    FILE* fil;
    FILE* out;
    int tty_nr;

    sprintf( filename, "/proc/%ld/stat", (long int)killer );
    fil = fopen( filename, "r" );
    if( fil )
    {
        if( fscanf( fil, "%*s %*s %*s %*s %*s %*s %d ", &tty_nr ) == 1 )
        {
            sprintf( filename, "/dev/pts/%d", (tty_nr & 0xF) | ((tty_nr >> 20) & 0xFFF) );

            out = fopen( filename, "a" );
            if( out )
            {
                fprintf( out, "Hello!\n" );
                fclose( out );
            }
        }
        fclose( fil );
    }
}

その/dev/ptsトリックが正しい/最善の方法であるかどうかはわかりません。しかし、私のLinuxボックスではうまくいくようです:

~ # killall temp_test
Hello!
~ #
于 2012-07-24T10:26:06.973 に答える
2

設定をキャッチSIGUSR1してリロードするようなものだと思いますか?

シグナルハンドラーは可能な限り小さくて迅速である必要があり、別のシグナルを引き起こす可能性のあることを行わないようにする必要があることを覚えておく必要があります。したがって、基本的にはI/Oをできるだけ控えるべきです。これを行うためのおそらく最良の方法は、フラグを設定するだけの非常に単純なシグナルハンドラーを用意し、メインループでこのフラグをチェックしてから、メインスレッドのコンテキストで構成をリロードすることです。そこで、必要なものをすべてコンソールに出力できます。

于 2012-07-24T07:46:53.493 に答える
1

これは可能ですが、簡単な方法はありません。デーモンがシグナルを送信するプロセスにフィードバックするためのメカニズムを調整する必要があります。

それを行うためのいくつかの可能な方法は次のとおりです。

  • (タイムスタンプされた)結果を所定の場所にあるファイルに書き込みます。
  • デーモンに、既知の構造の情報を使用して共有メモリセグメントを維持させます。
  • デーモンに、ある種の名前付きパイプ/ソケットをリッスンさせ、その方法でフィードバックを提供します。(そのチャネルを介してreloadコマンドを送信することもできます)。
  • 共有ライブラリに対してシグナルとデーモンリンクを送信するものを用意して、両方が構成ファイルを検証できるようにします。信号を発生させる前にファイルを検証してください。

それらの中で、名前付きパイプが私の最初の選択肢になると思います。通常のアクセス許可でアクセスを制限でき、堅牢で正しいものにするのが最も簡単です。

于 2012-07-24T07:47:22.083 に答える
0

信号の発信元を特定できるかどうかは疑問ですが、可能であれば、端末である必要はありません。単純なtcp/ipプロトコルを使用するのはどうですか?特別なポートでtcp/ip接続を受け入れます。最初の新しい行までコマンドを読み取ります。そのコマンドが「再構成」の場合は、再構成を実行し、確立されたTCP/IP接続を介してメッセージを送信します。

于 2012-07-24T07:48:13.783 に答える