2
reply = redisCommand(rcontext,"HGET %u %u",env->cr[3] ,KeyHandle);
if(reply == NULL)
{
printf("in preNtDeletKey rediscommand error ! and the err type is %d the string is %s \n" ,rcontext->err,rcontext->errstr)";
}

ここでエラーが発生しました。応答は NULL を返し、出力は次のとおりです。

preNtDeletKey rediscommand エラーで ! err タイプは 1 です 文字列は中断されたシステム コールです

私は自分のプロジェクトでこれを使用します。そして、私はhiredisソースでgrepが見つかりません中断されたシステムコールが見つかりません中断されたシステムコールを引き起こす理由を知りたいですどのようにhiredisが文字列をredisContextに書き込むか(ソースで見つからないため)

中断されたシステムコールを回避するにはどうすればよいですか?

4

2 に答える 2

6

Hiredisパッケージは、Redisプロトコルを使用してコマンドをマーシャリングし、Redisサーバーに送信します。次に、同期的に応答を待ちます。

ソケットを処理する関数は、hiredis.cファイルにあります。

int redisBufferRead(redisContext *c)
int redisBufferWrite(redisContext *c, int *done)

これらの関数では、EAGAINエラーは処理されますが、「システムコールの中断」メッセージに対応するEINTRエラーは処理されません。

その結果、hiredisが書き込みまたは(より可能性が高い)読み取り操作を実行しているときにプロセスが受信するUnixシグナルが操作を中断し、このエラーを引き起こす可能性があります。

まず、アプリケーションが受信する信号の種類を理解する必要があります。信号の性質とアプリケーションに応じて、この状況を処理するさまざまな方法があります。

  • Redis呼び出しを行う前にシグナルハンドラーをマスキングまたは延期する
  • シグナルをイベントループハンドラー(存在する場合)にバインドして、予期しないときにシグナルが処理されるのを回避します
  • すべてのシグナルを処理するために特定のスレッドを専用にします(そしてこのスレッドでのRedis呼び出しを回避します)
  • SA_RESTARTオプション(sigaction内)を使用して、中断されたシステムコールを自動的に再生するようにシステムに指示します
  • 操作を再試行してください(ただし、実行できない場合があります)

個人的には、より優雅な方法で状況を処理するために、hiredisを好みます(つまり、EAGAINのようにEINTRを処理します)。

アップデート:

EAGAINエラーは通常、次の2つの状況で返されます。

  • redisConnectNonBlockまたはredisConnectUnixNonBlock()を呼び出して非ブロッキングモードがアクティブ化された場合

  • 接続がブロッキングモード(デフォルト)で、タイムアウトを設定するためにredisSetTimeout()メソッドが呼び出された場合

クライアント側でredisSetTimeout()関数を呼び出すには、ソケットのSO_RCVTIMEOプロパティとSO_SNDTIMEOプロパティを設定するだけであることに注意してください。これは、サーバー側のアイドルタイムアウトであるRedis構成ファイルで定義されているタイムアウトとはまったく関係ありません(RedisサーバーはN秒を超えて非アクティブになっている場合に接続を閉じることができます)。

2番目の状況でEAGAINを取得するということは、Redisインスタンスが指定されたタイムアウトに対して十分に応答しないことを意味します。単にタイムアウトを増やすか、Redisサーバー側の遅延の問題をさらに調査することをお勧めします。

于 2012-04-06T10:15:46.197 に答える
0

手がかりはありませんが、簡単に検索すると、(Linuxカーネルでは)システムコールは何も問題がないときに中断される可能性があり、それが発生した場合、典型的なことはそれをやり直すことです。私の推測では、ここで行うことは何もないので、Redis データベースか、コードの一部がその状況を処理していません。http://www.win.tue.nl/~aeb/linux/lk/lk-4.html

于 2012-04-06T09:28:21.717 に答える