1

共有リソースを安全に更新するために、php スクリプトで次のコード フラグメントを使用しています。

$lock_id = sem_get( ftok( 'tmp/this.lock', 'r'));
sem_acquire($lock_id)
//do something
sem_release($lock_id)

多数のリクエストを使用してこのコードをストレス テストすると、エラーが発生します。

Warning: semop() failed acquiring SYSVSEM_SETVAL for key 0x1e: No space left on device in blahblah.php on line 1293

PHPソースは、SYSVSEM_SETVALの取得に失敗した場合の次のコードを示しています

while (semop(semid, sop, 3) == -1) {
    if (errno != EINTR) {
        php3_error(E_WARNING, "semop() failed acquiring SYSVSEM_SETVAL for key 0x%x: %s", key, strerror(errno));
        break;
    }
}

つまり、semop は EINTR で失敗します。man ページは、semop() システム コールがシグナルによって中断されたことを示しています。

私の質問は、このエラーを安全に無視して sem_acquire を再試行できるかどうかです。

編集:私はこの問題を誤解しています。以下に投稿した説明を参照してください。

ラジ

4

2 に答える 2

1

私は ENOSPC を無視しません (コードが示すように、EINTR 以外のものを取得しています)。以前に使い果たしたリソースを待っているビジー ループに陥る可能性があります。どこかのスペースが不足している場合は、その問題に確実に対処する必要があります。ENOSPC は一般的に、あなたが何かを失っていることを意味します。

いくつかのランダムなアイデア:

私は PHP 実装の専門家ではありませんがsem_get()、セマフォが必要になるたびに呼び出さないようにしています。代わりにハンドルを保管してください。一部のリソースが sem_get の各呼び出しに関連付けられている可能性があり、その場所でスペースが不足しています。

でエラーが返されることを確認しますsem_get()。これはコード スニペットですが、sema4 の取得に失敗した場合、取得しようとすると一貫性のない結果が得られますsem_op()(おそらく EINTR は理にかなっています)。

于 2008-11-07T16:27:17.687 に答える
0

この質問を投稿した後、私はコードを読み間違えたことに気づき、結論に飛びつきました。したがって、bogが指摘しているように、エラーはであり、ではありません。いくつか掘り下げた後、私はの理由を見つけました。UNDOバッファの数が使い果たされていました。数を増やしましたが、コードは問題なく実行されています。私はlをの値として使用しましたerrno == EINTRENOSPCEINTRENOSPCsemmnusemmni*semmssemmnu

于 2008-11-07T17:31:39.617 に答える