1

変数をグローバルにせず、また渡すことができないように、2 つの関数で変数を共有する方法はありますか? または、使用時に関数に変数を渡す方法はありsignal()ますか?

具体的には、ファイルを開いて作業し、かなり長い間開いたままにしておく main() があります。fdファイルの処理が完了すると、(およびその他の情報) main() 呼び出しを受け入れる小さな関数があります。

現在、致命的なシグナルをキャッチし、必要に応じて対処することで、物事をより堅牢にしようとしています。fd他のすべての必要な変数をグローバルにせずにこれを行う方法を理解することはできませんが。むしろ避けたいもの。

(void)signal(SIGINT, die);

死ぬ

static void die(int sig)
{
    endTrip(fd, &tripID); //Quickly writes a footer and fcloses
    exit(sig);
}

すべてをグローバルにするよりも良い解決策はありますか?

編集

このようなことは可能ですか

static void die(int sig, FILE *fd)
{
    const FILE *local_fd;
    if(sig == NULL)
        {local_fd = fd;}
    else
    {
        endTrip(local_fd, &tripID); //Quickly writes a footer and fcloses 
        exit(sig);
    }
}


main() {
  ...
  // When i open new file let die know.
  die(NULL, fd);
  ...
}
4

4 に答える 4

2

シグナルハンドラはすでにグローバルな状態です。1 つを使用している場合は、既に戻り値のポイントを通過しており、通常はカーネル空間に隠されているグローバル変数 (シグナル ハンドラー ポインター) にもかかわらず、既にグローバル変数を使用しています。この時点で、引数に別のグローバル変数を追加して、それで完了しても大したことではありません。

そうは言っても、おそらく設計全体が有効かどうかを検討する必要があります。シグナル ハンドラから stdio を使用することは、保証が難しい非常に特殊な状況を除いて有効ではありません。あなたの場合、シグナルハンドラーによって中断されたコードは同じFILEストリームで動作しているように見えるため、シグナルハンドラーからそれに触れることはほぼ確実に無効です。

また、プログラムがマルチスレッド化されている場合、またはマルチスレッド化されている場合にどうなるかを検討することもできます。プロセス全体に対してシグナル ハンドラーのセットは 1 つしかありませんが、複数のファイルが異なるスレッドで書き込まれている可能性があります。

このような問題を解決するにはさまざまな方法がありますが、最も簡単で移植性の高い方法は、パイプを開き、シグナル ハンドラーに何もせずにパイプに 1 バイトを書き込むことです。次に、メイン ループ コードは、パイプの読み取り側で入力を検出し (たとえば、selectまたはpollを使用)、シグナル ハンドラー コンテキストの外部で、独自のローカル変数にアクセスできる独自のコンテキストで処理します。

于 2012-08-22T05:19:26.830 に答える
0
static void die(int sig, FILE *fd) { 
    static const FILE *local_fd;
    if(sig == NULL) {
        local_fd = fd;
    }
    ...

次の関数呼び出しで local_fd を使い続けたいと思っていると思います。そのため、static const FILE *として宣言する必要があります。

于 2012-08-22T05:24:55.117 に答える
0

すべての変数をグローバルにする別の解決策は見当たりません。物事をきれいにするために、おそらくすべての変数を含む構造を作成できます。

于 2012-08-22T05:06:32.810 に答える
0

1 つのファイル内の 2 つ以上の関数間で変数を共有する通常の方法 (他のファイルで表示されるようにグローバルにしない) は、それをstatic変数にすることです。「fd」は通常、「ファイル記述子」(ファイル記述子) の省略形として使用されることに注意してくださいint。通常、a には省略形「fp」を使用しますFILE *

static FILE *local_fp;
static void die(int signum);

int main(void)
{
    local_fp = fopen("...");
    signal(SIGINT, die);
    ...
    ...use local_fp...
    fclose(local_fp);
    local_fp = 0;
    ...
    return(EXIT_SUCCESS);
}

static void die(int signum)
{
    if (local_fp != 0)
        fclose(local_fp);
    exit(EXIT_FAILURE);
}

これは、変数 にアクセスできる 2 つの関数を示していますlocal_fp。2 つの関数間で値またはポインターを引数として渡すか、変数 (グローバル、静的、または関数への引数として渡される) を使用して共有メモリにアクセスすることになる共有メモリのさまざまなトリックを除いて、ペアにする方法はありません。変数へのアクセスを共有する関数の。

あなたの関数をどうするかよくわかりませんし、信号が混合物にどのように適合するかもよくわかりません。

int main(void)戻り値の型について明示的に記述する必要があることに注意してください。C99 では、戻り値の型を省略できません (C11 も省略できません)。

于 2012-08-22T05:15:58.110 に答える