5

関数の戻りの失敗などのエラーケースをコードで処理できるようにしたいと思います。たとえばpthread_create、通常、私は以下の関数を使用します。

int thread_check1;
 pthread_t function;
 thread_check1 = pthread_create( &function, NULL, function_function,  NULL);
if(thread_check1 != 0){
   fprintf(stderr, "pthread_create error\n");
   exit(1);
}

エラーの場合を考慮すると、以下で行うように、(この特定の関数に対して)0が返されるまで同じ関数を呼び出すのは正しいでしょうか?

thread_check1 = pthread_create( &function, NULL, function_function,  NULL);
while(thread_check1 != 0){
    thread_check1 = pthread_create( &function, NULL, function_function,  NULL);
}

値を返す他のC関数に同じロジックを適用できますか?それ以外の場合、プログラムを終了せずに(関数が戻るための)エラーケースを処理することをどのように提案しますか?

4

4 に答える 4

3

あなたはそれを行うことができますが、より適切です。f戻り値が異なる関数があるとします。次のように実行できます。

tries_left = 1000;
do
{
    ret = f(params);
    if (ret == OK)
        break;
    else if (ret == SOMETHING_UNRECOVERABLE)
        /* break with failure */
    else if (ret == SOMETHING_FIXABLE)
        /* fix params */
    else
        /* sleep a little */
} while (--tries_left);

ここで考慮すべきことがたくさんあります。

  • 無限ループを避けてください。本質的に何か問題がある場合、ループに陥りたくはありません。したがって、いくつかの試行の後、中断して失敗したいと思うでしょう。ここでtries_left出番です。
  • 回復不能の場合は失敗します。エラーが問題を修正できないことを示している場合は、試行を中止してください。たとえば、ドライブをマウントしようとして/dev/sda6、存在しないと表示された場合、再試行しても意味がありません。
  • 実際に問題を処理してみてください。場合によっては、別のパラメーターを試すことができる場合があります。たとえば、バックアップ ファイルを作成しようとして作成できない場合は、ファイルのディレクトリまたは名前を変更して、もう一度やり直してください。
  • 100% CPU を使用しないでください。再試行する場合は、問題が解決するか、最大の CPU を使用しないようにするために、少なくとも試行の間に息抜きをしてください。

最後に、このように処理する必要があるさまざまな関数がある場合に繰り返しを避けるために、このすべてをマクロに入れて のようCHECK_AND_RETRY(f(params));に呼び出すことができます。機能に関係なく(一種の制限ですが、美しい解決策はありません)。

于 2013-01-04T16:35:26.850 に答える
1

そのようなエラーを処理することは絶対にお勧めしません。真の問題がある場合は、無限ループに陥ります。例として、ファイルがすでに使用されているときにファイルを開くことがあります。次のいずれかを実行する必要があります。

  • エラーを印刷/ログに記録し、実行を停止します。

  • 特定のエラーを許可します(ifに&&を追加します)。この例では、エラーコードが3の場合にのみ再試行します。

    if(thread_check1!= 0){

         If (thread_check1 == 3) retry;
    
于 2013-01-04T16:30:54.037 に答える
1

障害が発生した場合に何をすべきかは、要件によってのみ異なります。通常、エラーの種類(致命的、許容可能など)と、プログラムへの影響によって異なります。例に戻ると、スレッドの作成を妨げた問題は2回目または3回目の試行で解消されない可能性が高いため(ここでも要件と環境によって異なります)、スレッドの作成に失敗した場合は致命的なエラーとして扱われる可能性があります。おそらくここでより良いアプローチです。繰り返しになりますが、失敗した場合にプログラムを終了するかどうかはあなた次第です。プログラムはこのスレッドなしで実行を継続できますか?はいの場合、プログラムを終了する必要はありません。それ以外の場合-終了します。

于 2013-01-04T16:31:23.867 に答える
1

ジョーがすでに述べたように、それはあなたの要件とあなたが使いたい方法に大きく依存します。何かが失敗するときはいつでも、通常理由があります。たとえば、mallocゼロを返すと、使用可能なメモリはなくなります。

このような状況で実際に使用せずに新しいメモリを取得しようとするfreeと、通常は無限ループが発生するため、これを行うべきではありません。一方、ファイルを開きたいが、現在別のプロセスによってブロックされている場合は、同様のことを行うことができます。

ただし、このようなループは通常、CPUをビジー状態に保ち、他のプロセス/スレッドの速度を低下させることに注意してください。また、現在のソリューションの間にあるものを使用して、終了する前に数回試すこともできます。

error_count = 0;
thread_check1 = pthread_create( &function, NULL, function_function,  NULL);
while(thread_check1 != 0){
    sleep(1); // wait some time before we try again
    if(++error_count == 10){
        fprintf(stderr, "Could not create thread\n");
        return 1;
    }
    thread_check1 = pthread_create( &function, NULL, function_function,  NULL);
}
于 2013-01-04T16:29:20.380 に答える